1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <cstdlib> 17#include <cstring> 18#include <cinttypes> 19#include <iostream> 20#include <string> 21#include <thread> 22#include <string_view> 23 24#include "log_kmsg.h" 25#include "flow_control.h" 26#include "log_domains.h" 27#include "log_collector.h" 28 29namespace OHOS { 30namespace HiviewDFX { 31using namespace std; 32 33void LogCollector::InsertDropInfo(const HilogMsg &msg, int droppedCount) 34{ 35 string dropLog = to_string(droppedCount) + " line(s) dropped!"; 36 constexpr auto tag = "LOGLIMITD"sv; 37 std::vector<char> buffer(sizeof(HilogMsg) + tag.size() + dropLog.size() + 1, '\0'); 38 HilogMsg *dropMsg = reinterpret_cast<HilogMsg *>(buffer.data()); 39 if (dropMsg != nullptr) { 40 dropMsg->len = buffer.size(); 41 dropMsg->version = msg.version; 42 dropMsg->type = msg.type; 43 dropMsg->level = msg.level; 44 dropMsg->tagLen = tag.size(); 45 dropMsg->tv_sec = msg.tv_sec; 46 dropMsg->tv_nsec = msg.tv_nsec; 47 dropMsg->mono_sec = msg.mono_sec; 48 dropMsg->pid = msg.pid; 49 dropMsg->tid = msg.tid; 50 dropMsg->domain = msg.domain; 51 52 auto remainSize = buffer.size() - sizeof(HilogMsg); 53 if (memcpy_s(dropMsg->tag, remainSize, tag.data(), tag.size())) { 54 std::cerr << "Can't copy tag info of Drop Info message\n"; 55 } 56 57 remainSize -= tag.size(); 58 auto logTextPtr = dropMsg->tag + tag.size(); // log text is behind tag data 59 if (memcpy_s(logTextPtr, remainSize, dropLog.data(), dropLog.size() + 1)) { 60 std::cerr << "Can't copy log text info of Drop Info message\n"; 61 } 62 63 InsertLogToBuffer(*dropMsg); 64 } 65} 66#ifndef __RECV_MSG_WITH_UCRED_ 67void LogCollector::onDataRecv(std::vector<char>& data, int dataLen) 68#else 69void LogCollector::onDataRecv(const ucred& cred, std::vector<char>& data, int dataLen) 70#endif 71{ 72 if (dataLen < sizeof(HilogMsg)) { 73 return; 74 } 75 HilogMsg& msg = *(reinterpret_cast<HilogMsg *>(data.data())); 76 if (dataLen != msg.len) { 77 return; 78 } 79 // check domain id 80 if (IsValidDomain(static_cast<LogType>(msg.type), msg.domain) == false) { 81 return; 82 } 83#ifdef __RECV_MSG_WITH_UCRED_ 84 msg.pid = cred.pid; 85#endif 86 bool dropped = false; 87 // Domain flow control 88 do { 89 int ret = 0; 90 if (msg.type != static_cast<uint16_t>(LOG_APP) && flowControl && !debug) { 91 ret = FlowCtrlDomain(msg); 92 } 93 if (ret < 0) { 94 // dropping message 95 dropped = true; 96 break; 97 } else if (ret > 0) { 98 // >0 means a new statistic period start, "ret" is the number of dropping lines in last period 99 InsertDropInfo(msg, ret); 100 } 101 // If insert msg fail, return 0 102 if (InsertLogToBuffer(msg) == 0) { 103 return; 104 } 105 } while (0); 106 107 // Log statistics 108 if (countEnable) { 109 if (*(msg.tag + msg.tagLen - 1) != '\0') { 110 return; 111 } 112 StatsInfo info = { 113 .level = msg.level, 114 .type = msg.type, 115 .len = (msg.len - sizeof(HilogMsg) - 1 - 1), // don't count '\0' of tag and content 116 .dropped = dropped ? 1 : 0, 117 .domain = msg.domain, 118 .pid = msg.pid, 119 .tv_sec = msg.tv_sec, 120 .tv_nsec = msg.tv_nsec, 121 .mono_sec = msg.mono_sec, 122 .tag = msg.tag 123 }; 124 m_hilogBuffer.CountLog(info); 125 } 126} 127 128size_t LogCollector::InsertLogToBuffer(const HilogMsg& msg) 129{ 130 bool isFull = false; 131 return m_hilogBuffer.Insert(msg, isFull); 132} 133 134void LogCollector::SetLogFlowControl(bool on) 135{ 136 flowControl = on; 137} 138 139void LogCollector::SetDebuggable(bool on) 140{ 141 debug = on; 142} 143} // namespace HiviewDFX 144} // namespace OHOS 145