12498b56bSopenharmony_ci/* 22498b56bSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 32498b56bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 42498b56bSopenharmony_ci * you may not use this file except in compliance with the License. 52498b56bSopenharmony_ci * You may obtain a copy of the License at 62498b56bSopenharmony_ci * 72498b56bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 82498b56bSopenharmony_ci * 92498b56bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 102498b56bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 112498b56bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 122498b56bSopenharmony_ci * See the License for the specific language governing permissions and 132498b56bSopenharmony_ci * limitations under the License. 142498b56bSopenharmony_ci */ 152498b56bSopenharmony_ci 162498b56bSopenharmony_ci#include <cstring> 172498b56bSopenharmony_ci#include <thread> 182498b56bSopenharmony_ci#include <vector> 192498b56bSopenharmony_ci#include <sys/time.h> 202498b56bSopenharmony_ci#include <regex> 212498b56bSopenharmony_ci#include <string> 222498b56bSopenharmony_ci 232498b56bSopenharmony_ci#include <hilog_common.h> 242498b56bSopenharmony_ci#include <flow_control.h> 252498b56bSopenharmony_ci#include <log_timestamp.h> 262498b56bSopenharmony_ci#include <properties.h> 272498b56bSopenharmony_ci#include <log_utils.h> 282498b56bSopenharmony_ci 292498b56bSopenharmony_ci#include "log_buffer.h" 302498b56bSopenharmony_ci 312498b56bSopenharmony_cinamespace OHOS { 322498b56bSopenharmony_cinamespace HiviewDFX { 332498b56bSopenharmony_ciusing namespace std; 342498b56bSopenharmony_ci 352498b56bSopenharmony_cistatic size_t g_maxBufferSizeByType[LOG_TYPE_MAX] = {262144, 262144, 262144, 262144, 262144, 0}; 362498b56bSopenharmony_cistatic int GenerateHilogMsgInside(HilogMsg& hilogMsg, const string& msg, uint16_t logType); 372498b56bSopenharmony_ci 382498b56bSopenharmony_ci// LOG_ONLY_PRERELEASE and LOG_CORE use the same buffer. 392498b56bSopenharmony_cistatic inline int ConvertBufType(int type) 402498b56bSopenharmony_ci{ 412498b56bSopenharmony_ci return type == LOG_ONLY_PRERELEASE ? LOG_CORE : type; 422498b56bSopenharmony_ci} 432498b56bSopenharmony_ci 442498b56bSopenharmony_ciHilogBuffer::HilogBuffer(bool isSupportSkipLog) : m_isSupportSkipLog(isSupportSkipLog) 452498b56bSopenharmony_ci{ 462498b56bSopenharmony_ci for (int i = 0; i < LOG_TYPE_MAX; i++) { 472498b56bSopenharmony_ci sizeByType[i] = 0; 482498b56bSopenharmony_ci } 492498b56bSopenharmony_ci InitBuffLen(); 502498b56bSopenharmony_ci InitBuffHead(); 512498b56bSopenharmony_ci} 522498b56bSopenharmony_ci 532498b56bSopenharmony_civoid HilogBuffer::InitBuffLen() 542498b56bSopenharmony_ci{ 552498b56bSopenharmony_ci size_t global_size = GetBufferSize(LOG_TYPE_MAX, false); 562498b56bSopenharmony_ci size_t persist_global_size = GetBufferSize(LOG_TYPE_MAX, true); 572498b56bSopenharmony_ci for (int i = 0; i < LOG_TYPE_MAX; i++) { 582498b56bSopenharmony_ci size_t size = GetBufferSize(i, false); 592498b56bSopenharmony_ci size_t persist_size = GetBufferSize(i, true); 602498b56bSopenharmony_ci SetBuffLen(i, global_size); 612498b56bSopenharmony_ci SetBuffLen(i, persist_global_size); 622498b56bSopenharmony_ci SetBuffLen(i, size); 632498b56bSopenharmony_ci SetBuffLen(i, persist_size); 642498b56bSopenharmony_ci } 652498b56bSopenharmony_ci} 662498b56bSopenharmony_ci 672498b56bSopenharmony_civoid HilogBuffer::InitBuffHead() 682498b56bSopenharmony_ci{ 692498b56bSopenharmony_ci const string msg = "========Zeroth log of type: "; 702498b56bSopenharmony_ci std::vector<char> buf(MAX_LOG_LEN, 0); 712498b56bSopenharmony_ci HilogMsg *headMsg = reinterpret_cast<HilogMsg *>(buf.data()); 722498b56bSopenharmony_ci 732498b56bSopenharmony_ci for (uint16_t i = 0; i < LOG_TYPE_MAX; i++) { 742498b56bSopenharmony_ci string typeStr = LogType2Str(i); 752498b56bSopenharmony_ci if (typeStr == "invalid") { 762498b56bSopenharmony_ci continue; 772498b56bSopenharmony_ci } 782498b56bSopenharmony_ci string tmpStr = msg + typeStr; 792498b56bSopenharmony_ci if (GenerateHilogMsgInside(*headMsg, tmpStr, i) == RET_SUCCESS) { 802498b56bSopenharmony_ci bool isFull = false; 812498b56bSopenharmony_ci Insert(*headMsg, isFull); 822498b56bSopenharmony_ci } 832498b56bSopenharmony_ci } 842498b56bSopenharmony_ci} 852498b56bSopenharmony_ci 862498b56bSopenharmony_ciHilogBuffer::~HilogBuffer() {} 872498b56bSopenharmony_ci 882498b56bSopenharmony_cisize_t HilogBuffer::Insert(const HilogMsg& msg, bool& isFull) 892498b56bSopenharmony_ci{ 902498b56bSopenharmony_ci size_t elemSize = CONTENT_LEN((&msg)); /* include '\0' */ 912498b56bSopenharmony_ci if (unlikely(msg.tagLen > MAX_TAG_LEN || msg.tagLen == 0 || elemSize > MAX_LOG_LEN || 922498b56bSopenharmony_ci elemSize == 0 || msg.type >= LOG_TYPE_MAX)) { 932498b56bSopenharmony_ci return 0; 942498b56bSopenharmony_ci } 952498b56bSopenharmony_ci isFull = false; 962498b56bSopenharmony_ci { 972498b56bSopenharmony_ci std::lock_guard<decltype(hilogBufferMutex)> lock(hilogBufferMutex); 982498b56bSopenharmony_ci int bufferType = ConvertBufType(msg.type); 992498b56bSopenharmony_ci 1002498b56bSopenharmony_ci // Delete old entries when full 1012498b56bSopenharmony_ci if (elemSize + sizeByType[bufferType] >= g_maxBufferSizeByType[bufferType]) { 1022498b56bSopenharmony_ci // Drop 5% of maximum log when full 1032498b56bSopenharmony_ci std::list<HilogData>::iterator it = hilogDataList.begin(); 1042498b56bSopenharmony_ci static const float DROP_RATIO = 0.05; 1052498b56bSopenharmony_ci while (sizeByType[bufferType] > g_maxBufferSizeByType[bufferType] * (1 - DROP_RATIO) && 1062498b56bSopenharmony_ci it != hilogDataList.end()) { 1072498b56bSopenharmony_ci if (ConvertBufType((*it).type) != bufferType) { // Only remove old logs of the same type 1082498b56bSopenharmony_ci ++it; 1092498b56bSopenharmony_ci continue; 1102498b56bSopenharmony_ci } 1112498b56bSopenharmony_ci 1122498b56bSopenharmony_ci if (IsItemUsed(it)) { 1132498b56bSopenharmony_ci isFull = true; 1142498b56bSopenharmony_ci return 0; 1152498b56bSopenharmony_ci } 1162498b56bSopenharmony_ci 1172498b56bSopenharmony_ci OnDeleteItem(it, DeleteReason::BUFF_OVERFLOW); 1182498b56bSopenharmony_ci size_t cLen = it->len - it->tagLen; 1192498b56bSopenharmony_ci sizeByType[ConvertBufType((*it).type)] -= cLen; 1202498b56bSopenharmony_ci it = hilogDataList.erase(it); 1212498b56bSopenharmony_ci } 1222498b56bSopenharmony_ci 1232498b56bSopenharmony_ci // Re-confirm if enough elements has been removed 1242498b56bSopenharmony_ci if (sizeByType[bufferType] >= g_maxBufferSizeByType[bufferType]) { 1252498b56bSopenharmony_ci std::cout << "Failed to clean old logs." << std::endl; 1262498b56bSopenharmony_ci } 1272498b56bSopenharmony_ci } 1282498b56bSopenharmony_ci 1292498b56bSopenharmony_ci // Append new log into HilogBuffer 1302498b56bSopenharmony_ci hilogDataList.emplace_back(msg); 1312498b56bSopenharmony_ci // Update current size of HilogBuffer 1322498b56bSopenharmony_ci sizeByType[bufferType] += elemSize; 1332498b56bSopenharmony_ci OnPushBackedItem(hilogDataList); 1342498b56bSopenharmony_ci } 1352498b56bSopenharmony_ci 1362498b56bSopenharmony_ci // Notify readers about new element added 1372498b56bSopenharmony_ci OnNewItem(hilogDataList); 1382498b56bSopenharmony_ci return elemSize; 1392498b56bSopenharmony_ci} 1402498b56bSopenharmony_ci 1412498b56bSopenharmony_ci// Replace wildcard with regex 1422498b56bSopenharmony_cistatic std::string WildcardToRegex(const std::string& wildcard) 1432498b56bSopenharmony_ci{ 1442498b56bSopenharmony_ci // Original and Replacement char array 1452498b56bSopenharmony_ci const static char* WILDCARDS = "*?[]+.^&"; 1462498b56bSopenharmony_ci const static std::string REPLACEMENT_S[] = {".*", ".", "\\[", "\\]", "\\+", "\\.", "\\^", "\\&"}; 1472498b56bSopenharmony_ci // Modify every wildcard to regex 1482498b56bSopenharmony_ci std::string result = ""; 1492498b56bSopenharmony_ci for (char c : wildcard) { 1502498b56bSopenharmony_ci // strchr matches wildcard and char 1512498b56bSopenharmony_ci if (std::strchr(WILDCARDS, c) != nullptr) { 1522498b56bSopenharmony_ci size_t index = std::strchr(WILDCARDS, c) - WILDCARDS; 1532498b56bSopenharmony_ci result += REPLACEMENT_S[index]; 1542498b56bSopenharmony_ci } else { 1552498b56bSopenharmony_ci result += c; 1562498b56bSopenharmony_ci } 1572498b56bSopenharmony_ci } 1582498b56bSopenharmony_ci return result; 1592498b56bSopenharmony_ci} 1602498b56bSopenharmony_ci 1612498b56bSopenharmony_cistatic bool LogMatchFilter(const LogFilter& filter, const HilogData& logData) 1622498b56bSopenharmony_ci{ 1632498b56bSopenharmony_ci // types & levels match 1642498b56bSopenharmony_ci if (((static_cast<uint16_t>(0b01 << logData.type)) & filter.types) == 0) { 1652498b56bSopenharmony_ci return false; 1662498b56bSopenharmony_ci } 1672498b56bSopenharmony_ci if (((static_cast<uint16_t>(0b01 << logData.level)) & filter.levels) == 0) { 1682498b56bSopenharmony_ci return false; 1692498b56bSopenharmony_ci } 1702498b56bSopenharmony_ci 1712498b56bSopenharmony_ci int i = 0; 1722498b56bSopenharmony_ci // domain match 1732498b56bSopenharmony_ci static constexpr uint32_t LOW_BYTE = 0xFF; 1742498b56bSopenharmony_ci static constexpr uint32_t LOW_BYTE_REVERSE = ~LOW_BYTE; 1752498b56bSopenharmony_ci /* 1) domain id equals exactly: (0xd012345 == 0xd012345) 1762498b56bSopenharmony_ci 2) last 8 bits is sub domain id, if it's 0xFF, compare high 24 bits: 1772498b56bSopenharmony_ci (0xd0123ff & 0xffffff00 == 0xd012345 & 0xffffff00) */ 1782498b56bSopenharmony_ci bool match = false; 1792498b56bSopenharmony_ci for (i = 0; i < filter.domainCount; i++) { 1802498b56bSopenharmony_ci if ((logData.domain == filter.domains[i]) || ((static_cast<uint8_t>(filter.domains[i]) == LOW_BYTE) 1812498b56bSopenharmony_ci && ((logData.domain & LOW_BYTE_REVERSE) == (filter.domains[i] & LOW_BYTE_REVERSE)))) { 1822498b56bSopenharmony_ci match = true; 1832498b56bSopenharmony_ci break; 1842498b56bSopenharmony_ci } 1852498b56bSopenharmony_ci } 1862498b56bSopenharmony_ci if (filter.domainCount && match == filter.blackDomain) { 1872498b56bSopenharmony_ci return false; 1882498b56bSopenharmony_ci } 1892498b56bSopenharmony_ci match = false; 1902498b56bSopenharmony_ci // tag match 1912498b56bSopenharmony_ci for (i = 0; i < filter.tagCount; i++) { 1922498b56bSopenharmony_ci if (strcmp(logData.tag, filter.tags[i]) == 0) { 1932498b56bSopenharmony_ci match = true; 1942498b56bSopenharmony_ci break; 1952498b56bSopenharmony_ci } 1962498b56bSopenharmony_ci } 1972498b56bSopenharmony_ci if (filter.tagCount && match == filter.blackTag) { 1982498b56bSopenharmony_ci return false; 1992498b56bSopenharmony_ci } 2002498b56bSopenharmony_ci match = false; 2012498b56bSopenharmony_ci // pid match 2022498b56bSopenharmony_ci for (i = 0; i < filter.pidCount; i++) { 2032498b56bSopenharmony_ci if (logData.pid == filter.pids[i]) { 2042498b56bSopenharmony_ci match = true; 2052498b56bSopenharmony_ci break; 2062498b56bSopenharmony_ci } 2072498b56bSopenharmony_ci } 2082498b56bSopenharmony_ci if (filter.pidCount && match == filter.blackPid) { 2092498b56bSopenharmony_ci return false; 2102498b56bSopenharmony_ci } 2112498b56bSopenharmony_ci // regular expression match 2122498b56bSopenharmony_ci if (filter.regex[0] != 0) { 2132498b56bSopenharmony_ci // Added a WildcardToRegex function for invalid regex. 2142498b56bSopenharmony_ci std::string wildcardRegex = WildcardToRegex(filter.regex); 2152498b56bSopenharmony_ci std::regex regExpress(wildcardRegex); 2162498b56bSopenharmony_ci if (std::regex_search(logData.content, regExpress) == false) { 2172498b56bSopenharmony_ci return false; 2182498b56bSopenharmony_ci } 2192498b56bSopenharmony_ci } 2202498b56bSopenharmony_ci return true; 2212498b56bSopenharmony_ci} 2222498b56bSopenharmony_ci 2232498b56bSopenharmony_cistd::optional<HilogData> HilogBuffer::Query(const LogFilter& filter, const ReaderId& id, int tailCount) 2242498b56bSopenharmony_ci{ 2252498b56bSopenharmony_ci auto reader = GetReader(id); 2262498b56bSopenharmony_ci if (!reader) { 2272498b56bSopenharmony_ci std::cerr << "Reader not registered!\n"; 2282498b56bSopenharmony_ci return std::nullopt; 2292498b56bSopenharmony_ci } 2302498b56bSopenharmony_ci 2312498b56bSopenharmony_ci std::shared_lock<decltype(hilogBufferMutex)> lock(hilogBufferMutex); 2322498b56bSopenharmony_ci 2332498b56bSopenharmony_ci if (reader->m_msgList != &hilogDataList) { 2342498b56bSopenharmony_ci reader->m_msgList = &hilogDataList; 2352498b56bSopenharmony_ci if (tailCount == 0) { 2362498b56bSopenharmony_ci reader->m_pos = hilogDataList.begin(); 2372498b56bSopenharmony_ci } else { 2382498b56bSopenharmony_ci reader->m_pos = hilogDataList.end(); 2392498b56bSopenharmony_ci reader->m_pos--; 2402498b56bSopenharmony_ci } 2412498b56bSopenharmony_ci for (int i = 0; (i < tailCount) && (reader->m_pos != hilogDataList.begin());) { 2422498b56bSopenharmony_ci if (LogMatchFilter(filter, (*reader->m_pos))) { 2432498b56bSopenharmony_ci i++; 2442498b56bSopenharmony_ci } 2452498b56bSopenharmony_ci reader->m_pos--; 2462498b56bSopenharmony_ci } 2472498b56bSopenharmony_ci } 2482498b56bSopenharmony_ci 2492498b56bSopenharmony_ci if (reader->skipped) { 2502498b56bSopenharmony_ci const string msg = "========Slow reader missed log lines: "; 2512498b56bSopenharmony_ci const string tmpStr = msg + to_string(reader->skipped); 2522498b56bSopenharmony_ci std::vector<char> buf(MAX_LOG_LEN, 0); 2532498b56bSopenharmony_ci HilogMsg *headMsg = reinterpret_cast<HilogMsg *>(buf.data()); 2542498b56bSopenharmony_ci if (GenerateHilogMsgInside(*headMsg, tmpStr, LOG_CORE) == RET_SUCCESS) { 2552498b56bSopenharmony_ci const HilogData logData(*headMsg); 2562498b56bSopenharmony_ci reader->skipped = 0; 2572498b56bSopenharmony_ci return logData; 2582498b56bSopenharmony_ci } 2592498b56bSopenharmony_ci } 2602498b56bSopenharmony_ci 2612498b56bSopenharmony_ci while (reader->m_pos != hilogDataList.end()) { 2622498b56bSopenharmony_ci const HilogData& logData = *reader->m_pos; 2632498b56bSopenharmony_ci reader->m_pos++; 2642498b56bSopenharmony_ci if (LogMatchFilter(filter, logData)) { 2652498b56bSopenharmony_ci return logData; 2662498b56bSopenharmony_ci } 2672498b56bSopenharmony_ci } 2682498b56bSopenharmony_ci return std::nullopt; 2692498b56bSopenharmony_ci} 2702498b56bSopenharmony_ci 2712498b56bSopenharmony_ciint32_t HilogBuffer::Delete(uint16_t logType) 2722498b56bSopenharmony_ci{ 2732498b56bSopenharmony_ci if (logType >= LOG_TYPE_MAX) { 2742498b56bSopenharmony_ci return ERR_LOG_TYPE_INVALID; 2752498b56bSopenharmony_ci } 2762498b56bSopenharmony_ci size_t sum = 0; 2772498b56bSopenharmony_ci std::unique_lock<decltype(hilogBufferMutex)> lock(hilogBufferMutex); 2782498b56bSopenharmony_ci std::list<HilogData>::iterator it = hilogDataList.begin(); 2792498b56bSopenharmony_ci 2802498b56bSopenharmony_ci // Delete logs corresponding to queryCondition 2812498b56bSopenharmony_ci while (it != hilogDataList.end()) { 2822498b56bSopenharmony_ci // Only remove old logs of the same type 2832498b56bSopenharmony_ci if ((*it).type != logType) { 2842498b56bSopenharmony_ci ++it; 2852498b56bSopenharmony_ci continue; 2862498b56bSopenharmony_ci } 2872498b56bSopenharmony_ci // Delete corresponding logs 2882498b56bSopenharmony_ci OnDeleteItem(it, DeleteReason::CMD_CLEAR); 2892498b56bSopenharmony_ci 2902498b56bSopenharmony_ci size_t cLen = it->len - it->tagLen; 2912498b56bSopenharmony_ci sum += cLen; 2922498b56bSopenharmony_ci sizeByType[(*it).type] -= cLen; 2932498b56bSopenharmony_ci it = hilogDataList.erase(it); 2942498b56bSopenharmony_ci } 2952498b56bSopenharmony_ci return sum; 2962498b56bSopenharmony_ci} 2972498b56bSopenharmony_ci 2982498b56bSopenharmony_ciHilogBuffer::ReaderId HilogBuffer::CreateBufReader(std::function<void()> onNewDataCallback) 2992498b56bSopenharmony_ci{ 3002498b56bSopenharmony_ci std::unique_lock<decltype(m_logReaderMtx)> lock(m_logReaderMtx); 3012498b56bSopenharmony_ci auto reader = std::make_shared<BufferReader>(); 3022498b56bSopenharmony_ci if (reader != nullptr) { 3032498b56bSopenharmony_ci reader->skipped = 0; 3042498b56bSopenharmony_ci reader->m_onNewDataCallback = onNewDataCallback; 3052498b56bSopenharmony_ci } 3062498b56bSopenharmony_ci ReaderId id = reinterpret_cast<ReaderId>(reader.get()); 3072498b56bSopenharmony_ci m_logReaders.insert(std::make_pair(id, reader)); 3082498b56bSopenharmony_ci return id; 3092498b56bSopenharmony_ci} 3102498b56bSopenharmony_ci 3112498b56bSopenharmony_civoid HilogBuffer::RemoveBufReader(const ReaderId& id) 3122498b56bSopenharmony_ci{ 3132498b56bSopenharmony_ci std::unique_lock<decltype(m_logReaderMtx)> lock(m_logReaderMtx); 3142498b56bSopenharmony_ci auto it = m_logReaders.find(id); 3152498b56bSopenharmony_ci if (it != m_logReaders.end()) { 3162498b56bSopenharmony_ci m_logReaders.erase(it); 3172498b56bSopenharmony_ci } 3182498b56bSopenharmony_ci} 3192498b56bSopenharmony_ci 3202498b56bSopenharmony_cibool HilogBuffer::IsItemUsed(LogMsgContainer::iterator itemPos) 3212498b56bSopenharmony_ci{ 3222498b56bSopenharmony_ci if (m_isSupportSkipLog) { 3232498b56bSopenharmony_ci return false; 3242498b56bSopenharmony_ci } 3252498b56bSopenharmony_ci std::shared_lock<decltype(m_logReaderMtx)> lock(m_logReaderMtx); 3262498b56bSopenharmony_ci for (auto& [id, readerPtr] : m_logReaders) { 3272498b56bSopenharmony_ci if (readerPtr->m_pos == itemPos) { 3282498b56bSopenharmony_ci return true; 3292498b56bSopenharmony_ci } 3302498b56bSopenharmony_ci } 3312498b56bSopenharmony_ci return false; 3322498b56bSopenharmony_ci} 3332498b56bSopenharmony_ci 3342498b56bSopenharmony_civoid HilogBuffer::OnDeleteItem(LogMsgContainer::iterator itemPos, DeleteReason reason) 3352498b56bSopenharmony_ci{ 3362498b56bSopenharmony_ci std::shared_lock<decltype(m_logReaderMtx)> lock(m_logReaderMtx); 3372498b56bSopenharmony_ci for (auto& [id, readerPtr] : m_logReaders) { 3382498b56bSopenharmony_ci if (readerPtr->m_pos == itemPos) { 3392498b56bSopenharmony_ci readerPtr->m_pos = std::next(itemPos); 3402498b56bSopenharmony_ci if (reason == DeleteReason::BUFF_OVERFLOW) { 3412498b56bSopenharmony_ci readerPtr->skipped++; 3422498b56bSopenharmony_ci } 3432498b56bSopenharmony_ci } 3442498b56bSopenharmony_ci } 3452498b56bSopenharmony_ci} 3462498b56bSopenharmony_ci 3472498b56bSopenharmony_civoid HilogBuffer::OnPushBackedItem(LogMsgContainer& msgList) 3482498b56bSopenharmony_ci{ 3492498b56bSopenharmony_ci std::shared_lock<decltype(m_logReaderMtx)> lock(m_logReaderMtx); 3502498b56bSopenharmony_ci for (auto& [id, readerPtr] : m_logReaders) { 3512498b56bSopenharmony_ci if (readerPtr->m_pos == msgList.end()) { 3522498b56bSopenharmony_ci readerPtr->m_pos = std::prev(msgList.end()); 3532498b56bSopenharmony_ci } 3542498b56bSopenharmony_ci } 3552498b56bSopenharmony_ci} 3562498b56bSopenharmony_ci 3572498b56bSopenharmony_civoid HilogBuffer::OnNewItem(LogMsgContainer& msgList) 3582498b56bSopenharmony_ci{ 3592498b56bSopenharmony_ci std::shared_lock<decltype(m_logReaderMtx)> lock(m_logReaderMtx); 3602498b56bSopenharmony_ci for (auto& [id, readerPtr] : m_logReaders) { 3612498b56bSopenharmony_ci if (readerPtr->m_msgList == &msgList && readerPtr->m_onNewDataCallback) { 3622498b56bSopenharmony_ci readerPtr->m_onNewDataCallback(); 3632498b56bSopenharmony_ci } 3642498b56bSopenharmony_ci } 3652498b56bSopenharmony_ci} 3662498b56bSopenharmony_ci 3672498b56bSopenharmony_cistd::shared_ptr<HilogBuffer::BufferReader> HilogBuffer::GetReader(const ReaderId& id) 3682498b56bSopenharmony_ci{ 3692498b56bSopenharmony_ci std::shared_lock<decltype(m_logReaderMtx)> lock(m_logReaderMtx); 3702498b56bSopenharmony_ci auto it = m_logReaders.find(id); 3712498b56bSopenharmony_ci if (it != m_logReaders.end()) { 3722498b56bSopenharmony_ci return it->second; 3732498b56bSopenharmony_ci } 3742498b56bSopenharmony_ci return std::shared_ptr<HilogBuffer::BufferReader>(); 3752498b56bSopenharmony_ci} 3762498b56bSopenharmony_ci 3772498b56bSopenharmony_ciint64_t HilogBuffer::GetBuffLen(uint16_t logType) 3782498b56bSopenharmony_ci{ 3792498b56bSopenharmony_ci if (logType >= LOG_TYPE_MAX) { 3802498b56bSopenharmony_ci return ERR_LOG_TYPE_INVALID; 3812498b56bSopenharmony_ci } 3822498b56bSopenharmony_ci uint64_t buffSize = g_maxBufferSizeByType[logType]; 3832498b56bSopenharmony_ci return buffSize; 3842498b56bSopenharmony_ci} 3852498b56bSopenharmony_ci 3862498b56bSopenharmony_ciint32_t HilogBuffer::SetBuffLen(uint16_t logType, uint64_t buffSize) 3872498b56bSopenharmony_ci{ 3882498b56bSopenharmony_ci if (logType >= LOG_TYPE_MAX) { 3892498b56bSopenharmony_ci return ERR_LOG_TYPE_INVALID; 3902498b56bSopenharmony_ci } 3912498b56bSopenharmony_ci if (buffSize < MIN_BUFFER_SIZE || buffSize > MAX_BUFFER_SIZE) { 3922498b56bSopenharmony_ci return ERR_BUFF_SIZE_INVALID; 3932498b56bSopenharmony_ci } 3942498b56bSopenharmony_ci std::unique_lock<decltype(hilogBufferMutex)> lock(hilogBufferMutex); 3952498b56bSopenharmony_ci g_maxBufferSizeByType[logType] = buffSize; 3962498b56bSopenharmony_ci return RET_SUCCESS; 3972498b56bSopenharmony_ci} 3982498b56bSopenharmony_ci 3992498b56bSopenharmony_civoid HilogBuffer::CountLog(const StatsInfo &info) 4002498b56bSopenharmony_ci{ 4012498b56bSopenharmony_ci stats.Count(info); 4022498b56bSopenharmony_ci} 4032498b56bSopenharmony_ci 4042498b56bSopenharmony_civoid HilogBuffer::ResetStats() 4052498b56bSopenharmony_ci{ 4062498b56bSopenharmony_ci stats.Reset(); 4072498b56bSopenharmony_ci} 4082498b56bSopenharmony_ci 4092498b56bSopenharmony_ciLogStats& HilogBuffer::GetStatsInfo() 4102498b56bSopenharmony_ci{ 4112498b56bSopenharmony_ci return stats; 4122498b56bSopenharmony_ci} 4132498b56bSopenharmony_ci 4142498b56bSopenharmony_cistatic int GenerateHilogMsgInside(HilogMsg& hilogMsg, const string& msg, uint16_t logType) 4152498b56bSopenharmony_ci{ 4162498b56bSopenharmony_ci const string tag = "HiLog"; 4172498b56bSopenharmony_ci size_t contentLen = tag.length() + 1 + msg.length() + 1; 4182498b56bSopenharmony_ci hilogMsg.len = static_cast<uint16_t>(sizeof(HilogMsg) + contentLen); 4192498b56bSopenharmony_ci hilogMsg.len = hilogMsg.len > MAX_LOG_LEN ? MAX_LOG_LEN : hilogMsg.len; 4202498b56bSopenharmony_ci contentLen = hilogMsg.len - static_cast<uint16_t>(sizeof(HilogMsg)); 4212498b56bSopenharmony_ci 4222498b56bSopenharmony_ci struct timespec ts = {0}; 4232498b56bSopenharmony_ci (void)clock_gettime(CLOCK_REALTIME, &ts); 4242498b56bSopenharmony_ci struct timespec ts_mono = {0}; 4252498b56bSopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC, &ts_mono); 4262498b56bSopenharmony_ci hilogMsg.tv_sec = static_cast<uint32_t>(ts.tv_sec); 4272498b56bSopenharmony_ci hilogMsg.tv_nsec = static_cast<uint32_t>(ts.tv_nsec); 4282498b56bSopenharmony_ci hilogMsg.mono_sec = static_cast<uint32_t>(ts_mono.tv_nsec); 4292498b56bSopenharmony_ci hilogMsg.type = logType; 4302498b56bSopenharmony_ci hilogMsg.level = LOG_INFO; 4312498b56bSopenharmony_ci hilogMsg.pid = 0; 4322498b56bSopenharmony_ci hilogMsg.tid = 0; 4332498b56bSopenharmony_ci hilogMsg.domain = 0; 4342498b56bSopenharmony_ci hilogMsg.tagLen = tag.length() + 1; 4352498b56bSopenharmony_ci if (memcpy_s(hilogMsg.tag, contentLen, tag.c_str(), hilogMsg.tagLen) != 0) { 4362498b56bSopenharmony_ci return RET_FAIL; 4372498b56bSopenharmony_ci } 4382498b56bSopenharmony_ci if (memcpy_s(hilogMsg.tag + hilogMsg.tagLen, contentLen - hilogMsg.tagLen, msg.c_str(), msg.length() + 1) != 0) { 4392498b56bSopenharmony_ci return RET_FAIL; 4402498b56bSopenharmony_ci } 4412498b56bSopenharmony_ci 4422498b56bSopenharmony_ci return RET_SUCCESS; 4432498b56bSopenharmony_ci} 4442498b56bSopenharmony_ci} // namespace HiviewDFX 4452498b56bSopenharmony_ci} // namespace OHOS 446