diff --git a/frameworks/native/include/hilog_common.h b/frameworks/native/include/hilog_common.h index c556374d82ed5d0b925afcc0ff3ea9d943232cb2..8e3fbc4c41389f5f426297b2d0d9ff5c19ca3e5b 100644 --- a/frameworks/native/include/hilog_common.h +++ b/frameworks/native/include/hilog_common.h @@ -46,6 +46,9 @@ #define ONE_MB (1UL<<20) #define ONE_GB (1UL<<30) #define ONE_TB (1ULL<<40) +#define TYPE_ALL 0xffff +#define DOMAIN_ALL 0xffffffff +#define LEVEL_ALL 0xffff const long long NSEC = 1000000000LL; const long long US = 1000000LL; const long long NS2US = 1000LL; diff --git a/frameworks/native/include/hilogtool_msg.h b/frameworks/native/include/hilogtool_msg.h index 1123a5f3c7dda2d47c4126e2bfa59a51978ee181..e5212a5b248f3f9930dc829163a0a137af4740fb 100644 --- a/frameworks/native/include/hilogtool_msg.h +++ b/frameworks/native/include/hilogtool_msg.h @@ -47,7 +47,9 @@ typedef enum { MC_REQ_FLOW_CONTROL, // set flow control request MC_RSP_FLOW_CONTROL, // set flow control response MC_REQ_LOG_CLEAR, // clear log request - MC_RSP_LOG_CLEAR // clear log response + MC_RSP_LOG_CLEAR, // clear log response + MC_REQ_STATISTIC_INFO_WAIT, + MC_RSP_STATISTIC_INFO_WAIT } OperationCmd; /* @@ -198,26 +200,27 @@ typedef struct { } StatisticInfoQueryRequest; typedef struct { - MessageHeader msgHeader; int32_t result; + uint32_t tv_sec; uint16_t logType; uint32_t domain; - uint64_t printLen; - uint64_t cacheLen; - int32_t dropped; + size_t printLen; + size_t cacheLen; + size_t dropped; +} StatisticInfoResult; + +typedef struct { + MessageHeader msgHeader; + StatisticInfoResult statisticInfoRst[]; } StatisticInfoQueryResponse; typedef struct { MessageHeader msgHeader; - uint16_t logType; - uint32_t domain; } StatisticInfoClearRequest; typedef struct { MessageHeader msgHeader; int32_t result; - uint16_t logType; - uint32_t domain; } StatisticInfoClearResponse; typedef struct { diff --git a/services/hilogd/BUILD.gn b/services/hilogd/BUILD.gn index 46d3cf4d049a279a361608b6471f513337749152..ec2a3ba80961ae4462d98ac196f10a98136e38d3 100644 --- a/services/hilogd/BUILD.gn +++ b/services/hilogd/BUILD.gn @@ -32,6 +32,7 @@ ohos_executable("hilogd") { "log_persister_rotator.cpp", "log_querier.cpp", "log_reader.cpp", + "log_statistic.cpp", "main.cpp", ] configs = [ ":hilogd_config" ] diff --git a/services/hilogd/cmd_executor.cpp b/services/hilogd/cmd_executor.cpp index 6c3fd6f9fa36aeca5eeeceff3c037e0d0495b16d..1d8aca8588275088953986bdee3e64bd8f35e5c5 100644 --- a/services/hilogd/cmd_executor.cpp +++ b/services/hilogd/cmd_executor.cpp @@ -120,7 +120,7 @@ void CmdExecutor::ClientEventLoop(std::unique_ptr handler) assert(clientInfoIt != m_clients.end()); prctl(PR_SET_NAME, "hilogd.query"); - auto logQuerier = std::make_shared(std::move(handler), m_hilogBuffer); + auto logQuerier = std::make_shared(std::move(handler), m_hilogBuffer, m_logStatistic); logQuerier->LogQuerierThreadFunc(logQuerier); std::lock_guard ul(m_finishedClientAccess); diff --git a/services/hilogd/flow_control_init.cpp b/services/hilogd/flow_control_init.cpp index caf40b9c72e952e801164bf13fc3a51eb504d555..0db961588a8eeeb4c4c098bc6dc700bde5356b64 100644 --- a/services/hilogd/flow_control_init.cpp +++ b/services/hilogd/flow_control_init.cpp @@ -42,51 +42,6 @@ using DomainInfo = struct { static std::unordered_map g_domainMap; -static int32_t g_typeDropped[LOG_TYPE_MAX]; -static std::unordered_map g_domainDropped; - -void ClearDroppedByType() -{ - int i; - for (i = 0; i < LOG_TYPE_MAX; i++) { - g_typeDropped[i] = 0; - } -} - -void ClearDroppedByDomain() -{ - std::unordered_map::iterator it; - for (it = g_domainDropped.begin(); it != g_domainDropped.end(); ++it) { - it->second = 0; - } -} - -void IncreaseDropped(uint32_t domainId, uint16_t logType) -{ - std::unordered_map::iterator it; - g_typeDropped[logType]++; - it = g_domainDropped.find(domainId); - if (it != g_domainDropped.end()) { - it->second++; - } else { - g_domainDropped.insert({ domainId, 1 }); - } -} - -int32_t GetDroppedByType(uint16_t logType) -{ - return g_typeDropped[logType]; -} - -int32_t GetDroppedByDomain(uint32_t domainId) -{ - std::unordered_map::iterator it = g_domainDropped.find(domainId); - if (it != g_domainDropped.end()) { - return it->second; - } - return 0; -} - void ParseDomainQuota(std::string &domainStr) { if (domainStr.empty() || domainStr.at(0) == '#') { @@ -153,8 +108,6 @@ int32_t InitDomainFlowCtrl() ParseDomainQuota(line); } ifs.close(); - ClearDroppedByType(); - ClearDroppedByDomain(); return 0; } @@ -178,7 +131,6 @@ int FlowCtrlDomain(HilogMsg* hilogMsg) it->second->sumLen += logLen; ret = 0; } else { /* over quota */ - IncreaseDropped(domainId, hilogMsg->type); it->second->dropped++; ret = -1; } diff --git a/services/hilogd/include/cmd_executor.h b/services/hilogd/include/cmd_executor.h index 1ae86b77de3b0638ba75647d979c91be0ac6b4e8..d4fc313dbfacbe5cb1b33367d1beb94daa0e1cef 100644 --- a/services/hilogd/include/cmd_executor.h +++ b/services/hilogd/include/cmd_executor.h @@ -22,6 +22,7 @@ #include #include "log_buffer.h" +#include "log_statistic.h" namespace OHOS { namespace HiviewDFX { @@ -32,7 +33,8 @@ struct ClientThread { class CmdExecutor { public: - CmdExecutor(HilogBuffer& buffer) : m_hilogBuffer(buffer) {} + CmdExecutor(HilogBuffer& buffer, LogStatistic& logStatistic) : m_hilogBuffer(buffer), + m_logStatistic(logStatistic) {} ~CmdExecutor(); void MainLoop(); private: @@ -45,6 +47,7 @@ private: std::mutex m_clientAccess; std::vector m_finishedClients; std::mutex m_finishedClientAccess; + LogStatistic& m_logStatistic; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/services/hilogd/include/flow_control_init.h b/services/hilogd/include/flow_control_init.h index 4278202ded0576bc866d9a9ae40be486af83f983..988c894bd36bb8b3daf3c79339dd7367005ee98c 100644 --- a/services/hilogd/include/flow_control_init.h +++ b/services/hilogd/include/flow_control_init.h @@ -22,10 +22,6 @@ namespace OHOS { namespace HiviewDFX { int32_t InitDomainFlowCtrl(); int FlowCtrlDomain(HilogMsg* hilogMsg); -int32_t GetDroppedByType(uint16_t logType); -int32_t GetDroppedByDomain(uint32_t domainId); -void ClearDroppedByType(); -void ClearDroppedByDomain(); } } #endif diff --git a/services/hilogd/include/log_buffer.h b/services/hilogd/include/log_buffer.h index 5dd12f96637bc32283ba9d7b7145b16e5ccb618f..22554b62817c14deb39062f474df43086745e9e5 100644 --- a/services/hilogd/include/log_buffer.h +++ b/services/hilogd/include/log_buffer.h @@ -25,12 +25,13 @@ #include #include "log_reader.h" +#include "log_statistic.h" namespace OHOS { namespace HiviewDFX { class HilogBuffer { public: - HilogBuffer(); + HilogBuffer(LogStatistic& statistic); ~HilogBuffer(); std::vector> logReaderList; @@ -43,10 +44,6 @@ public: size_t Delete(uint16_t logType); size_t GetBuffLen(uint16_t logType); size_t SetBuffLen(uint16_t logType, uint64_t buffSize); - int32_t GetStatisticInfoByLog(uint16_t logType, uint64_t& printLen, uint64_t& cacheLen, int32_t& dropped); - int32_t GetStatisticInfoByDomain(uint32_t domain, uint64_t& printLen, uint64_t& cacheLen, int32_t& dropped); - int32_t ClearStatisticInfoByLog(uint16_t logType); - int32_t ClearStatisticInfoByDomain(uint32_t domain); void GetBufferLock(); void ReleaseBufferLock(); private: @@ -55,14 +52,9 @@ private: std::list hilogDataList; std::list hilogKlogList; std::shared_mutex hilogBufferMutex; - std::map cacheLenByDomain; - std::map printLenByDomain; - std::map droppedByDomain; - uint64_t cacheLenByType[LOG_TYPE_MAX]; - uint64_t droppedByType[LOG_TYPE_MAX]; - uint64_t printLenByType[LOG_TYPE_MAX]; bool ConditionMatch(std::shared_ptr reader); void ReturnNoLog(std::shared_ptr reader); + LogStatistic& m_logStatistic; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/services/hilogd/include/log_collector.h b/services/hilogd/include/log_collector.h index aa55b2fd34cc0c42841c825f749f9ef31ac8e4d7..9aa08df7ce54636560fb2e00e1440350d05a82cc 100644 --- a/services/hilogd/include/log_collector.h +++ b/services/hilogd/include/log_collector.h @@ -18,12 +18,13 @@ #include "log_buffer.h" #include "hilog_input_socket_server.h" +#include "log_statistic.h" namespace OHOS { namespace HiviewDFX { class LogCollector { public: - LogCollector(HilogBuffer& buffer) : m_hilogBuffer(buffer) {} + LogCollector(HilogBuffer& buffer, LogStatistic& statistic) : m_hilogBuffer(buffer), m_logStatistic(statistic) {} void InsertDropInfo(const HilogMsg &msg, int droppedCount); size_t InsertLogToBuffer(const HilogMsg& msg); #ifndef __RECV_MSG_WITH_UCRED_ @@ -34,6 +35,7 @@ public: ~LogCollector() = default; private: HilogBuffer& m_hilogBuffer; + LogStatistic& m_logStatistic; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/services/hilogd/include/log_querier.h b/services/hilogd/include/log_querier.h index d14360daa2c029482fe6476a7c14dc48b7f7c1e9..aa845efb47abb1bb0651e2926032fb90bcb67d24 100644 --- a/services/hilogd/include/log_querier.h +++ b/services/hilogd/include/log_querier.h @@ -23,7 +23,7 @@ namespace OHOS { namespace HiviewDFX { class LogQuerier : public LogReader { public: - LogQuerier(std::unique_ptr handler, HilogBuffer& buffer); + LogQuerier(std::unique_ptr handler, HilogBuffer& buffer, LogStatistic& statistic); static void LogQuerierThreadFunc(std::shared_ptr logReader); int WriteData(LogQueryResponse& rsp, OptRef pData); int WriteData(OptRef pData); diff --git a/services/hilogd/include/log_reader.h b/services/hilogd/include/log_reader.h index 6235656f6e5804fc3517bd0ac3e3e1f1986a6ebe..0cd1180bda6fe5fc2f282a676f01a7f7b16e304f 100644 --- a/services/hilogd/include/log_reader.h +++ b/services/hilogd/include/log_reader.h @@ -25,6 +25,7 @@ #include "log_msg_wrapper.h" #include "hilogtool_msg.h" #include "socket.h" +#include "log_statistic.h" namespace OHOS { namespace HiviewDFX { @@ -60,7 +61,8 @@ public: QueryCondition queryCondition; std::unique_ptr hilogtoolConnectSocket; bool isNotified; - + int infoIndex; + QueryResults queryInfo; LogReader(); virtual ~LogReader(); bool GetReload() const; @@ -76,6 +78,7 @@ protected: unsigned int sendId = 1; uint8_t cmd = 0; static HilogBuffer* hilogBuffer; + static LogStatistic* logStatistic; private: bool isReload = true; diff --git a/services/hilogd/include/log_statistic.h b/services/hilogd/include/log_statistic.h new file mode 100644 index 0000000000000000000000000000000000000000..99a277ef67bb4a460fe166f7897f09fd7fe85261 --- /dev/null +++ b/services/hilogd/include/log_statistic.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LOG_STATISTIC_H +#define LOG_STATISTIC_H + +#include +#include +#include "hilog_common.h" +#include "log_data.h" + +namespace OHOS { +namespace HiviewDFX { +struct Statistic { + size_t dropped; + size_t printed; + size_t cached; +}; + +struct StatisticInfo { + uint16_t logType; + uint32_t domain; + Statistic statistic; +}; + +struct QueryResult { + uint32_t tv_sec; + Statistic statistic; +}; + +struct QueryResults { + uint32_t tv_sec; + std::vector infoVec; +}; + +class LogStatistic { +public: + LogStatistic(); + ~LogStatistic(); + int Printed(const HilogMsg& msg); + int Cached(const HilogMsg& msg); + int CacheDropped(const HilogData& data); + int Dropped(const HilogMsg& msg); + int GetByType(uint16_t logType, QueryResult& result); + int GetByDomain(uint32_t domain, QueryResult& result); + int GetStatistic(QueryResults & results); + int ResetStatistic(); +private: + std::unordered_map statisticMap[LOG_TYPE_MAX]; + Statistic* GetStatsInfo(uint16_t logType, uint32_t domain); + void ResetTime(); + uint32_t time_sec; +}; +} +} +#endif diff --git a/services/hilogd/log_buffer.cpp b/services/hilogd/log_buffer.cpp index 9fc55d748f7978a879545d29c7b99ab6f3262de2..4984c2c59815fa3d61b89cb6da281209e13441fa 100644 --- a/services/hilogd/log_buffer.cpp +++ b/services/hilogd/log_buffer.cpp @@ -19,6 +19,7 @@ #include "hilog_common.h" #include "flow_control_init.h" #include "log_time_stamp.h" + namespace OHOS { namespace HiviewDFX { using namespace std; @@ -31,14 +32,11 @@ const int DOMAIN_FUZZY_MASK = 0xdffff; const int DOMAIN_MODULE_BITS = 8; const int MAX_TIME_DIFF = 5; -HilogBuffer::HilogBuffer() +HilogBuffer::HilogBuffer(LogStatistic& statistic) : m_logStatistic(statistic) { size = 0; for (int i = 0; i < LOG_TYPE_MAX; i++) { sizeByType[i] = 0; - cacheLenByType[i] = 0; - printLenByType[i] = 0; - droppedByType[i] = 0; } } @@ -82,9 +80,9 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) size_t cLen = it->len - it->tag_len; size -= cLen; sizeByType[(*it).type] -= cLen; + m_logStatistic.CacheDropped(*it); it = msgList.erase(it); - } - + } // Re-confirm if enough elements has been removed if (sizeByType[msg.type] >= (size_t)g_maxBufferSizeByType[msg.type]) { std::cout << "Failed to clean old logs." << std::endl; @@ -113,16 +111,10 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) // Update current size of HilogBuffer size += eleSize; sizeByType[msg.type] += eleSize; - cacheLenByType[msg.type] += eleSize; - if (cacheLenByDomain.count(msg.domain) == 0) { - cacheLenByDomain.insert(pair(msg.domain, eleSize)); - } else { - cacheLenByDomain[msg.domain] += eleSize; - } + m_logStatistic.Cached(msg); return eleSize; } - bool HilogBuffer::Query(std::shared_ptr reader) { uint16_t qTypes = reader->queryCondition.types; @@ -144,13 +136,6 @@ bool HilogBuffer::Query(std::shared_ptr reader) if (ConditionMatch(reader)) { reader->SetSendId(SENDIDA); reader->WriteData(*(reader->readPos)); - printLenByType[reader->readPos->type] += strlen(reader->readPos->content); - if (printLenByDomain.count(reader->readPos->domain) == 0) { - printLenByDomain.insert(pair(reader->readPos->domain, - strlen(reader->readPos->content))); - } else { - printLenByDomain[reader->readPos->domain] += strlen(reader->readPos->content); - } reader->readPos++; hilogBufferMutex.unlock_shared(); return true; @@ -200,6 +185,7 @@ size_t HilogBuffer::Delete(uint16_t logType) sum += cLen; sizeByType[(*it).type] -= cLen; size -= cLen; + m_logStatistic.CacheDropped(*it); it = msgList.erase(it); } @@ -258,47 +244,6 @@ size_t HilogBuffer::SetBuffLen(uint16_t logType, uint64_t buffSize) return buffSize; } -int32_t HilogBuffer::GetStatisticInfoByLog(uint16_t logType, uint64_t& printLen, uint64_t& cacheLen, int32_t& dropped) -{ - if (logType >= LOG_TYPE_MAX) { - return ERR_LOG_TYPE_INVALID; - } - printLen = printLenByType[logType]; - cacheLen = cacheLenByType[logType]; - dropped = GetDroppedByType(logType); - return 0; -} - -int32_t HilogBuffer::GetStatisticInfoByDomain(uint32_t domain, uint64_t& printLen, uint64_t& cacheLen, - int32_t& dropped) -{ - printLen = printLenByDomain[domain]; - cacheLen = cacheLenByDomain[domain]; - dropped = GetDroppedByDomain(domain); - return 0; -} - -int32_t HilogBuffer::ClearStatisticInfoByLog(uint16_t logType) -{ - if (logType >= LOG_TYPE_MAX) { - return ERR_LOG_TYPE_INVALID; - } - ClearDroppedByType(); - printLenByType[logType] = 0; - cacheLenByType[logType] = 0; - droppedByType[logType] = 0; - return 0; -} - -int32_t HilogBuffer::ClearStatisticInfoByDomain(uint32_t domain) -{ - ClearDroppedByDomain(); - printLenByDomain[domain] = 0; - cacheLenByDomain[domain] = 0; - droppedByDomain[domain] = 0; - return 0; -} - bool HilogBuffer::ConditionMatch(std::shared_ptr reader) { /* domain patterns: diff --git a/services/hilogd/log_collector.cpp b/services/hilogd/log_collector.cpp index cf22f79231ed61354e50425ed51c93f6ba80e8dc..0a5c176f43f2c49948a50521a52ba4244441e365 100644 --- a/services/hilogd/log_collector.cpp +++ b/services/hilogd/log_collector.cpp @@ -76,6 +76,7 @@ void LogCollector::onDataRecv(const ucred& cred, std::vector& data) #ifdef __RECV_MSG_WITH_UCRED_ msg->pid = cred.pid; #endif + m_logStatistic.Printed(*msg); // Domain flow control int ret = FlowCtrlDomain(msg); if (ret < 0) { @@ -84,6 +85,7 @@ void LogCollector::onDataRecv(const ucred& cred, std::vector& data) } else if (ret > 0) { /* if >0 !Need print how many lines was dopped */ // store info how many was dropped InsertDropInfo(*msg, ret); + m_logStatistic.Dropped(*msg); } InsertLogToBuffer(*msg); } diff --git a/services/hilogd/log_querier.cpp b/services/hilogd/log_querier.cpp index 7abe32823cc74bf48083db53f4fab200238d1a0b..38e398302e6c671e5fe4cc77918fe159f31bcf21 100644 --- a/services/hilogd/log_querier.cpp +++ b/services/hilogd/log_querier.cpp @@ -45,7 +45,6 @@ string g_logPersisterDir = HILOG_FILE_DIR; constexpr int DEFAULT_LOG_LEVEL = 1< logReader, logReader->hilogtoolConnectSocket->Write(msgToSend, sendMsgLen + sizeof(MessageHeader)); } -void HandleInfoQueryRequest(char* reqMsg, std::shared_ptr logReader, HilogBuffer* buffer) +void HandleInfoQueryRequest(char* reqMsg, std::shared_ptr logReader, HilogBuffer* buffer, + LogStatistic* statistic) { - char msgToSend[MAX_DATA_LEN]; - int32_t rst = 0; - memset_s(msgToSend, MAX_DATA_LEN, 0, MAX_DATA_LEN); + char msgToSend[MAX_DATA_LEN] = {0}; + int rst = 0, rstNum = 0; StatisticInfoQueryRequest* pStatisticInfoQueryReq = reinterpret_cast(reqMsg); StatisticInfoQueryResponse* pStatisticInfoQueryRsp = reinterpret_cast(msgToSend); - if (pStatisticInfoQueryReq->domain == 0xffffffff) { - pStatisticInfoQueryRsp->logType = pStatisticInfoQueryReq->logType; - pStatisticInfoQueryRsp->domain = pStatisticInfoQueryReq->domain; - rst = buffer->GetStatisticInfoByLog(pStatisticInfoQueryReq->logType, pStatisticInfoQueryRsp->printLen, - pStatisticInfoQueryRsp->cacheLen, pStatisticInfoQueryRsp->dropped); - pStatisticInfoQueryRsp->result = (rst < 0) ? rst : RET_SUCCESS; + StatisticInfoResult* pRst = reinterpret_cast(pStatisticInfoQueryRsp->statisticInfoRst); + if (pStatisticInfoQueryReq->logType == TYPE_ALL && pStatisticInfoQueryReq->domain == DOMAIN_ALL) { + QueryResults info; + rst = statistic->GetStatistic(info); + for (uint32_t i = 0; i < info.infoVec.size(); i++) { + rstNum++; + if (sizeof(StatisticInfoResult) * rstNum + sizeof(MessageHeader) > MAX_DATA_LEN) { + rstNum--; + uint16_t sendMsgLen = sizeof(StatisticInfoResult) * rstNum; + SetMsgHead(pStatisticInfoQueryRsp->msgHeader, MC_RSP_STATISTIC_INFO_WAIT, sendMsgLen); + logReader->hilogtoolConnectSocket->Write(msgToSend, sendMsgLen + sizeof(MessageHeader)); + logReader->queryInfo.tv_sec = info.tv_sec; + logReader->queryInfo.infoVec = info.infoVec; + logReader->infoIndex = i; + return; + } + pRst->tv_sec = info.tv_sec; + pRst->result = (rst < 0) ? rst : RET_SUCCESS; + pRst->logType = info.infoVec[i].logType; + pRst->domain = info.infoVec[i].domain; + pRst->dropped = info.infoVec[i].statistic.dropped; + pRst->printLen = info.infoVec[i].statistic.printed; + pRst->cacheLen = info.infoVec[i].statistic.cached; + pRst++; + } } else { - pStatisticInfoQueryRsp->logType = pStatisticInfoQueryReq->logType; - pStatisticInfoQueryRsp->domain = pStatisticInfoQueryReq->domain; - rst = buffer->GetStatisticInfoByDomain(pStatisticInfoQueryReq->domain, pStatisticInfoQueryRsp->printLen, - pStatisticInfoQueryRsp->cacheLen, pStatisticInfoQueryRsp->dropped); - pStatisticInfoQueryRsp->result = (rst < 0) ? rst : RET_SUCCESS; + QueryResult info; + pRst->logType = pStatisticInfoQueryReq->logType; + pRst->domain = pStatisticInfoQueryReq->domain; + if (pStatisticInfoQueryReq->logType != TYPE_ALL) { + rst = statistic->GetByType(pStatisticInfoQueryReq->logType, info); + } else if (pStatisticInfoQueryReq->domain != DOMAIN_ALL) { + rst = statistic->GetByDomain(pStatisticInfoQueryReq->domain, info); + } + pRst->tv_sec = info.tv_sec; + pRst->dropped = info.statistic.dropped; + pRst->printLen = info.statistic.printed; + pRst->cacheLen = info.statistic.cached; + pRst->result = (rst < 0) ? rst : RET_SUCCESS; + rstNum++; + } + uint16_t sendMsgLen = sizeof(StatisticInfoResult) * rstNum; + SetMsgHead(pStatisticInfoQueryRsp->msgHeader, MC_RSP_STATISTIC_INFO_QUERY, sendMsgLen); + logReader->hilogtoolConnectSocket->Write(msgToSend, sendMsgLen + sizeof(MessageHeader)); +} + +void HandleInfoWaitRequest(std::shared_ptr logReader) +{ + char msgToSend[MAX_DATA_LEN] = {0}; + int rstNum = 0; + StatisticInfoQueryResponse* pStatisticInfoQueryRsp = reinterpret_cast(msgToSend); + StatisticInfoResult* pRst = reinterpret_cast(pStatisticInfoQueryRsp->statisticInfoRst); + for (uint32_t i = logReader->infoIndex; i < logReader->queryInfo.infoVec.size(); i++) { + rstNum++; + if (sizeof(StatisticInfoResult) * rstNum + sizeof(MessageHeader) > MAX_DATA_LEN) { + rstNum--; + uint16_t sendMsgLen = sizeof(StatisticInfoResult) * rstNum; + SetMsgHead(pStatisticInfoQueryRsp->msgHeader, MC_RSP_STATISTIC_INFO_WAIT, sendMsgLen); + logReader->hilogtoolConnectSocket->Write(msgToSend, sendMsgLen + sizeof(MessageHeader)); + logReader->infoIndex = i; + return; + } + pRst->tv_sec = logReader->queryInfo.tv_sec; + pRst->result = RET_SUCCESS; + pRst->logType = logReader->queryInfo.infoVec[i].logType; + pRst->domain = logReader->queryInfo.infoVec[i].domain; + pRst->dropped = logReader->queryInfo.infoVec[i].statistic.dropped; + pRst->printLen = logReader->queryInfo.infoVec[i].statistic.printed; + pRst->cacheLen = logReader->queryInfo.infoVec[i].statistic.cached; + pRst++; } - SetMsgHead(pStatisticInfoQueryRsp->msgHeader, MC_RSP_STATISTIC_INFO_QUERY, sizeof(StatisticInfoQueryResponse) - - sizeof(MessageHeader)); - logReader->hilogtoolConnectSocket->Write(msgToSend, sizeof(StatisticInfoQueryResponse)); + uint16_t sendMsgLen = sizeof(StatisticInfoResult) * rstNum; + SetMsgHead(pStatisticInfoQueryRsp->msgHeader, MC_RSP_STATISTIC_INFO_QUERY, sendMsgLen); + logReader->hilogtoolConnectSocket->Write(msgToSend, sendMsgLen + sizeof(MessageHeader)); } -void HandleInfoClearRequest(char* reqMsg, std::shared_ptr logReader, HilogBuffer* buffer) +void HandleInfoClearRequest(char* reqMsg, std::shared_ptr logReader, HilogBuffer* buffer, + LogStatistic* statistic) { char msgToSend[MAX_DATA_LEN]; int32_t rst = 0; memset_s(msgToSend, MAX_DATA_LEN, 0, MAX_DATA_LEN); - StatisticInfoClearRequest* pStatisticInfoClearReq = reinterpret_cast(reqMsg); StatisticInfoClearResponse* pStatisticInfoClearRsp = reinterpret_cast(msgToSend); - if (pStatisticInfoClearReq->domain == 0xffffffff) { - pStatisticInfoClearRsp->logType = pStatisticInfoClearReq->logType; - pStatisticInfoClearRsp->domain = pStatisticInfoClearReq->domain; - rst = buffer->ClearStatisticInfoByLog(pStatisticInfoClearReq->logType); - pStatisticInfoClearRsp->result = (rst < 0) ? rst : RET_SUCCESS; - } else { - pStatisticInfoClearRsp->logType = pStatisticInfoClearReq->logType; - pStatisticInfoClearRsp->domain = pStatisticInfoClearReq->domain; - rst = buffer->ClearStatisticInfoByDomain(pStatisticInfoClearReq->domain); - pStatisticInfoClearRsp->result = (rst < 0) ? rst : RET_SUCCESS; - } + rst = statistic->ResetStatistic(); + pStatisticInfoClearRsp->result = (rst < 0) ? rst : RET_SUCCESS; SetMsgHead(pStatisticInfoClearRsp->msgHeader, MC_RSP_STATISTIC_INFO_CLEAR, sizeof(StatisticInfoClearResponse) - sizeof(MessageHeader)); logReader->hilogtoolConnectSocket->Write(msgToSend, sizeof(StatisticInfoClearResponse)); @@ -485,12 +533,12 @@ void LogQuerier::LogQuerierThreadFunc(std::shared_ptr logReader) int readRes = 0; LogQueryRequest* qRstMsg = nullptr; NextRequest* nRstMsg = nullptr; - - while ((readRes = logReader->hilogtoolConnectSocket->Read(g_tempBuffer, MAX_DATA_LEN - 1)) > 0) { - MessageHeader *header = (MessageHeader *)g_tempBuffer; + char tempBuffer[MAX_DATA_LEN] = {0}; + while ((readRes = logReader->hilogtoolConnectSocket->Read(tempBuffer, MAX_DATA_LEN - 1)) > 0) { + MessageHeader *header = (MessageHeader *)tempBuffer; switch (header->msgType) { case LOG_QUERY_REQUEST: - qRstMsg = (LogQueryRequest*) g_tempBuffer; + qRstMsg = (LogQueryRequest*) tempBuffer; SetCondition(logReader, *qRstMsg); if (!LogTypeForbidden(logReader->queryCondition.types)) { return; @@ -498,34 +546,37 @@ void LogQuerier::LogQuerierThreadFunc(std::shared_ptr logReader) HandleLogQueryRequest(logReader, *hilogBuffer); break; case NEXT_REQUEST: - nRstMsg = (NextRequest*) g_tempBuffer; + nRstMsg = (NextRequest*) tempBuffer; if (nRstMsg->sendId == SENDIDA) { HandleNextRequest(logReader, *hilogBuffer); } break; case MC_REQ_LOG_PERSIST_START: - HandlePersistStartRequest(g_tempBuffer, logReader, *hilogBuffer); + HandlePersistStartRequest(tempBuffer, logReader, *hilogBuffer); break; case MC_REQ_LOG_PERSIST_STOP: - HandlePersistDeleteRequest(g_tempBuffer, logReader); + HandlePersistDeleteRequest(tempBuffer, logReader); break; case MC_REQ_LOG_PERSIST_QUERY: - HandlePersistQueryRequest(g_tempBuffer, logReader); + HandlePersistQueryRequest(tempBuffer, logReader); break; case MC_REQ_BUFFER_RESIZE: - HandleBufferResizeRequest(g_tempBuffer, logReader, hilogBuffer); + HandleBufferResizeRequest(tempBuffer, logReader, hilogBuffer); break; case MC_REQ_BUFFER_SIZE: - HandleBufferSizeRequest(g_tempBuffer, logReader, hilogBuffer); + HandleBufferSizeRequest(tempBuffer, logReader, hilogBuffer); break; case MC_REQ_STATISTIC_INFO_QUERY: - HandleInfoQueryRequest(g_tempBuffer, logReader, hilogBuffer); + HandleInfoQueryRequest(tempBuffer, logReader, hilogBuffer, logStatistic); + break; + case MC_REQ_STATISTIC_INFO_WAIT: + HandleInfoWaitRequest(logReader); break; case MC_REQ_STATISTIC_INFO_CLEAR: - HandleInfoClearRequest(g_tempBuffer, logReader, hilogBuffer); + HandleInfoClearRequest(tempBuffer, logReader, hilogBuffer, logStatistic); break; case MC_REQ_LOG_CLEAR: - HandleBufferClearRequest(g_tempBuffer, logReader, hilogBuffer); + HandleBufferClearRequest(tempBuffer, logReader, hilogBuffer); break; default: break; @@ -534,10 +585,11 @@ void LogQuerier::LogQuerierThreadFunc(std::shared_ptr logReader) hilogBuffer->RemoveLogReader(logReader); } -LogQuerier::LogQuerier(std::unique_ptr handler, HilogBuffer& buffer) +LogQuerier::LogQuerier(std::unique_ptr handler, HilogBuffer& buffer, LogStatistic& statistic) { hilogtoolConnectSocket = std::move(handler); hilogBuffer = &buffer; + logStatistic = &statistic; } int LogQuerier::WriteData(LogQueryResponse& rsp, OptRef pData) diff --git a/services/hilogd/log_reader.cpp b/services/hilogd/log_reader.cpp index b3c7b1747177e8235c159a59b08e3085d8444ba3..56e557d95b407eefb75619be63f9ef491fdd0abe 100644 --- a/services/hilogd/log_reader.cpp +++ b/services/hilogd/log_reader.cpp @@ -27,6 +27,8 @@ namespace HiviewDFX { using namespace std; HilogBuffer* LogReader::hilogBuffer = nullptr; +LogStatistic* LogReader::logStatistic = nullptr; + LogReader::LogReader() { isNotified = false; diff --git a/services/hilogd/log_statistic.cpp b/services/hilogd/log_statistic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da6a0f0892319582119f3bbed1be9b2fcf61f9b1 --- /dev/null +++ b/services/hilogd/log_statistic.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "log_statistic.h" +namespace OHOS { +namespace HiviewDFX { +LogStatistic::LogStatistic() +{ + ResetTime(); +} + +LogStatistic::~LogStatistic() +{} + +void LogStatistic::ResetTime() +{ + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + time_sec = ts.tv_sec; +} + +Statistic* LogStatistic::GetStatsInfo(uint16_t logType, uint32_t domain) +{ + std::unordered_map::iterator it = statisticMap[logType].find(domain); + if (it != statisticMap[logType].end()) { + return &(it->second); + } + return nullptr; +} + +int LogStatistic::Printed(const HilogMsg& msg) +{ + Statistic* info = GetStatsInfo(msg.type, msg.domain); + if (info) { + info->printed += CONTENT_LEN((&msg)); + } else { + Statistic tmp; + tmp.printed = CONTENT_LEN((&msg)); + tmp.cached = 0; + tmp.dropped = 0; + statisticMap[msg.type].insert({msg.domain, tmp}); + } + + return 0; +} + +int LogStatistic::Cached(const HilogMsg& msg) +{ + Statistic* info = GetStatsInfo(msg.type, msg.domain); + if (info) { + info->cached += CONTENT_LEN((&msg)); + } else { + Statistic tmp; + tmp.printed = 0; + tmp.cached = CONTENT_LEN((&msg)); + tmp.dropped = 0; + statisticMap[msg.type].insert({msg.domain, tmp}); + } + return 0; +} + +int LogStatistic::CacheDropped(const HilogData& data) +{ + Statistic* info = GetStatsInfo(data.type, data.domain); + if (info) { + info->cached -= (data.len - data.tag_len); + } + return 0; +} + +int LogStatistic::Dropped(const HilogMsg& msg) +{ + Statistic* info = GetStatsInfo(msg.type, msg.domain); + if (info) { + info->printed++; + } else { + Statistic tmp; + tmp.printed = 0; + tmp.cached = 0; + tmp.dropped = 1; + statisticMap[msg.type].insert({msg.domain, tmp}); + } + return 0; +} + +int LogStatistic::GetByType(uint16_t logType, QueryResult& result) +{ + result.tv_sec = time_sec; + std::unordered_map::iterator it; + for (it = statisticMap[logType].begin(); it != statisticMap[logType].end(); ++it) { + result.statistic.printed += it->second.printed; + result.statistic.cached += it->second.cached; + result.statistic.dropped += it->second.dropped; + } + return 0; +} + +int LogStatistic::GetByDomain(uint32_t domain, QueryResult& result) +{ + result.tv_sec = time_sec; + std::unordered_map::iterator it; + for (int i = 0; i < LOG_TYPE_MAX; i++) { + std::unordered_map::iterator it = statisticMap[i].find(domain); + if (it != statisticMap[i].end()) { + result.statistic.printed = it->second.printed; + result.statistic.cached = it->second.cached; + result.statistic.dropped = it->second.dropped; + break; + } + } + return 0; +} + +int LogStatistic::GetStatistic(QueryResults & results) +{ + results.tv_sec = time_sec; + std::vector domainVec; + for (int i = 0; i < LOG_TYPE_MAX; i++) { + std::unordered_map::iterator it; + for (it = statisticMap[i].begin(); it != statisticMap[i].end(); ++it) { + domainVec.emplace_back(it->first); + } + } + sort(domainVec.begin(), domainVec.end()); + std::unordered_map::iterator it; + for (uint32_t domain : domainVec) { + for (int i = 0; i < LOG_TYPE_MAX; i++) { + it = statisticMap[i].find(domain); + if (it != statisticMap[i].end()) { + StatisticInfo info; + info.logType = i; + info.domain = it->first; + info.statistic.printed = it->second.printed; + info.statistic.cached = it->second.cached; + info.statistic.dropped = it->second.dropped; + results.infoVec.emplace_back(info); + break; + } + } + } + return 0; +} + +int LogStatistic::ResetStatistic() +{ + ResetTime(); + std::unordered_map::iterator it; + for (int i = 0; i < LOG_TYPE_MAX; i++) { + for (it = statisticMap[i].begin(); it != statisticMap[i].end(); ++it) { + it->second.printed = 0; + it->second.dropped = 0; + } + } + return 0; +} +} +} diff --git a/services/hilogd/main.cpp b/services/hilogd/main.cpp index 7ba78afc304f27b2648cbad559f1825062365620..8e4d8840e800a1bbab7a72554b5224fbcd883b66 100644 --- a/services/hilogd/main.cpp +++ b/services/hilogd/main.cpp @@ -58,7 +58,8 @@ static void SigHandler(int sig) int HilogdEntry() { - HilogBuffer hilogBuffer; + LogStatistic logStatistic; + HilogBuffer hilogBuffer(logStatistic); umask(HILOG_FILE_MASK); #ifdef DEBUG int fd = open(HILOG_FILE_DIR"hilogd.txt", O_WRONLY | O_APPEND); @@ -74,13 +75,13 @@ int HilogdEntry() // Start log_collector #ifndef __RECV_MSG_WITH_UCRED_ - auto onDataReceive = [&hilogBuffer](std::vector& data) { - static LogCollector logCollector(hilogBuffer); + auto onDataReceive = [&hilogBuffer, &logStatistic](std::vector& data) { + static LogCollector logCollector(hilogBuffer, logStatistic); logCollector.onDataRecv(data); }; #else - auto onDataReceive = [&hilogBuffer](const ucred& cred, std::vector& data) { - static LogCollector logCollector(hilogBuffer); + auto onDataReceive = [&hilogBuffer, &logStatistic](const ucred& cred, std::vector& data) { + static LogCollector logCollector(hilogBuffer, logStatistic); logCollector.onDataRecv(cred, data); }; #endif @@ -100,17 +101,17 @@ int HilogdEntry() incomingLogsServer.RunServingThread(); } - auto startupCheckTask = std::async(std::launch::async, [&hilogBuffer]() { + auto startupCheckTask = std::async(std::launch::async, [&hilogBuffer, &logStatistic]() { prctl(PR_SET_NAME, "hilogd.pst_res"); - std::shared_ptr logQuerier = std::make_shared(nullptr, hilogBuffer); + std::shared_ptr logQuerier = std::make_shared(nullptr, hilogBuffer, logStatistic); logQuerier->RestorePersistJobs(hilogBuffer); }); - auto kmsgTask = std::async(std::launch::async, [&hilogBuffer]() { + auto kmsgTask = std::async(std::launch::async, [&hilogBuffer, &logStatistic]() { LogKmsg logKmsg(hilogBuffer); logKmsg.ReadAllKmsg(); }); - CmdExecutor cmdExecutor(hilogBuffer); + CmdExecutor cmdExecutor(hilogBuffer, logStatistic); cmdExecutor.MainLoop(); return 0; } diff --git a/services/hilogtool/include/log_controller.h b/services/hilogtool/include/log_controller.h index c9369fca77241f07c9ed79ef801d9b3feeb5b839..7b9a69ababcf6bf12899c8984756bc2d8bcacb89 100644 --- a/services/hilogtool/include/log_controller.h +++ b/services/hilogtool/include/log_controller.h @@ -41,6 +41,7 @@ int32_t StatisticInfoOp(SeqPacketSocketClient& controller, uint8_t msgCmd, int32_t LogClearOp(SeqPacketSocketClient& controller, uint8_t msgCmd, const std::string& logTypeStr); int32_t LogPersistOp(SeqPacketSocketClient& controller, uint8_t msgCmd, LogPersistParam* logPersistParam); int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType, SetPropertyParam* propertyParm); +int32_t StatisticWaitOp(SeqPacketSocketClient& controller, char* recvBuff, int recvLen); } // namespace HiviewDFX } // namespace OHOS #endif diff --git a/services/hilogtool/log_controller.cpp b/services/hilogtool/log_controller.cpp index cb27e04b5362b7b741c0fdb598d72cee356b7cd4..d0295b0773242d30e63d4a319f41085d2f7aac7b 100644 --- a/services/hilogtool/log_controller.cpp +++ b/services/hilogtool/log_controller.cpp @@ -38,6 +38,7 @@ const int LOG_PERSIST_FILE_SIZE = 4 * ONE_MB; const int LOG_PERSIST_FILE_NUM = 10; const uint32_t DEFAULT_JOBID = 1; const uint32_t DEFAULT_KMSG_JOBID = 2; + void SetMsgHead(MessageHeader* msgHeader, const uint8_t msgCmd, const uint16_t msgLen) { if (!msgHeader) { @@ -85,7 +86,7 @@ uint16_t GetLogType(const string& logTypeStr) } else if (logTypeStr == "kmsg") { logType = LOG_KMSG; } else { - return 0xffff; + return TYPE_ALL; } return logType; } @@ -145,7 +146,7 @@ uint16_t GetLogLevel(const std::string& logLevelStr, std::string& logLevel) logLevel = "F"; return LOG_FATAL; } - return 0xffff; + return LEVEL_ALL; } string SetDefaultLogType(const std::string& logTypeStr) @@ -271,7 +272,7 @@ int32_t BufferSizeOp(SeqPacketSocketClient& controller, uint8_t msgCmd, const st } for (iter = 0; iter < logTypeNum; iter++) { pBuffSizeMsg->logType = GetLogType(vecLogType[iter]); - if (pBuffSizeMsg->logType == 0xffff) { + if (pBuffSizeMsg->logType == TYPE_ALL) { cout << ParseErrorCode(ERR_LOG_TYPE_INVALID) << endl; return RET_FAIL; } @@ -290,7 +291,7 @@ int32_t BufferSizeOp(SeqPacketSocketClient& controller, uint8_t msgCmd, const st } for (iter = 0; iter < logTypeNum; iter++) { pBuffResizeMsg->logType = GetLogType(vecLogType[iter]); - if (pBuffResizeMsg->logType == 0xffff) { + if (pBuffResizeMsg->logType == TYPE_ALL) { cout << ParseErrorCode(ERR_LOG_TYPE_INVALID) << endl; return RET_FAIL; } @@ -311,19 +312,19 @@ int32_t BufferSizeOp(SeqPacketSocketClient& controller, uint8_t msgCmd, const st int32_t StatisticInfoOp(SeqPacketSocketClient& controller, uint8_t msgCmd, const std::string& logTypeStr, const std::string& domainStr) { - if ((logTypeStr != "" && domainStr != "") || (logTypeStr == "" && domainStr == "")) { + if ((logTypeStr != "" && domainStr != "")) { return RET_FAIL; } uint16_t logType = GetLogType(logTypeStr); uint32_t domain; if (domainStr == "") { - domain = 0xffffffff; - if (logType == 0xffff) { - cout << ParseErrorCode(ERR_LOG_TYPE_INVALID) << endl; - return RET_FAIL; - } + domain = DOMAIN_ALL; } else { - std::istringstream(domainStr) >> domain; + if (domainStr.rfind("0x", 0) == 0 || domainStr.rfind("0X", 0) == 0) { + std::istringstream(domainStr) >> hex >> domain; + } else { + std::istringstream(domainStr) >> domain; + } if (domain == 0 || domain > DOMAIN_MAX_SCOPE) { cout << ParseErrorCode(ERR_DOMAIN_INVALID) << endl; return RET_FAIL; @@ -340,8 +341,6 @@ int32_t StatisticInfoOp(SeqPacketSocketClient& controller, uint8_t msgCmd, } case MC_REQ_STATISTIC_INFO_CLEAR: { StatisticInfoClearRequest staInfoClearReq = {{0}}; - staInfoClearReq.logType = logType; - staInfoClearReq.domain = domain; SetMsgHead(&staInfoClearReq.msgHeader, msgCmd, sizeof(StatisticInfoClearRequest) - sizeof(MessageHeader)); controller.WriteAll((char*)&staInfoClearReq, sizeof(StatisticInfoClearRequest)); break; @@ -352,6 +351,31 @@ int32_t StatisticInfoOp(SeqPacketSocketClient& controller, uint8_t msgCmd, return RET_SUCCESS; } +int32_t StatisticWaitOp(SeqPacketSocketClient& controller, char* recvBuff, int recvLen) +{ + while (1) { + MessageHeader* msgHeader = (MessageHeader*)recvBuff; + uint8_t msgCmd = msgHeader->msgType; + ControlCmdResult(recvBuff); + if (msgCmd == MC_RSP_STATISTIC_INFO_WAIT) { + StatisticInfoQueryRequest staInfoQueryReq = {{0}}; + staInfoQueryReq.logType = TYPE_ALL; + staInfoQueryReq.domain = DOMAIN_ALL; + SetMsgHead(&staInfoQueryReq.msgHeader, MC_REQ_STATISTIC_INFO_WAIT, + sizeof(StatisticInfoQueryRequest) - sizeof(MessageHeader)); + controller.WriteAll((char*)&staInfoQueryReq, sizeof(StatisticInfoQueryRequest)); + if (controller.RecvMsg(recvBuff, recvLen) == 0) { + fprintf(stderr, "Unexpected EOF %s\n", strerror(errno)); + exit(1); + return 0; + } + } else { + break; + } + } + return 0; +} + int32_t LogClearOp(SeqPacketSocketClient& controller, uint8_t msgCmd, const std::string& logTypeStr) { char msgToSend[MSG_MAX_LEN] = {0}; @@ -373,7 +397,7 @@ int32_t LogClearOp(SeqPacketSocketClient& controller, uint8_t msgCmd, const std: } for (iter = 0; iter < logTypeNum; iter++) { pLogClearMsg->logType = GetLogType(vecLogType[iter]); - if (pLogClearMsg->logType == 0xffff) { + if (pLogClearMsg->logType == TYPE_ALL) { cout << ParseErrorCode(ERR_LOG_TYPE_INVALID) << endl; return RET_FAIL; } @@ -411,7 +435,7 @@ int32_t LogPersistOp(SeqPacketSocketClient& controller, uint8_t msgCmd, LogPersi } for (iter = 0; iter < logTypeNum; iter++) { uint16_t tmpType = GetLogType(vecLogType[iter]); - if (tmpType == 0xffff) { + if (tmpType == TYPE_ALL) { cout << ParseErrorCode(ERR_LOG_TYPE_INVALID) << endl; return RET_FAIL; } @@ -478,7 +502,7 @@ int32_t LogPersistOp(SeqPacketSocketClient& controller, uint8_t msgCmd, LogPersi for (iter = 0; iter < logTypeNum; iter++) { uint16_t tmpType = GetLogType(vecLogType[iter]); - if (tmpType == 0xffff) { + if (tmpType == TYPE_ALL) { cout << ParseErrorCode(ERR_LOG_TYPE_INVALID) << endl; return RET_FAIL; } @@ -545,7 +569,7 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType std::string keyPre = GetPropertyName(PROP_DOMAIN_LOG_LEVEL); for (iter = 0; iter < domainNum; iter++) { key = keyPre + vecDomain[iter]; - if (GetLogLevel(propertyParm->logLevelStr, value) == 0xffff) { + if (GetLogLevel(propertyParm->logLevelStr, value) == LEVEL_ALL) { continue; } PropertySet(key.c_str(), value.c_str()); @@ -555,7 +579,7 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType std::string keyPre = GetPropertyName(PROP_TAG_LOG_LEVEL); for (iter = 0; iter < tagNum; iter++) { key = keyPre + vecTag[iter]; - if (GetLogLevel(propertyParm->logLevelStr, value) == 0xffff) { + if (GetLogLevel(propertyParm->logLevelStr, value) == LEVEL_ALL) { continue; } PropertySet(key.c_str(), value.c_str()); @@ -563,7 +587,7 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType } } else { key = GetPropertyName(PROP_GLOBAL_LOG_LEVEL); - if (GetLogLevel(propertyParm->logLevelStr, value) == 0xffff) { + if (GetLogLevel(propertyParm->logLevelStr, value) == LEVEL_ALL) { return RET_FAIL; } PropertySet(key.c_str(), value.c_str()); diff --git a/services/hilogtool/log_display.cpp b/services/hilogtool/log_display.cpp index 28844ffe07d982caba04fcabe00b520a190f1bca..39a27e21eaf7076a67bec4ff1577aa56713d2e5b 100644 --- a/services/hilogtool/log_display.cpp +++ b/services/hilogtool/log_display.cpp @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include "hilog/log.h" #include "format.h" #include "log_controller.h" @@ -67,7 +70,12 @@ unordered_map errorMsg {ERR_COMMAND_INVALID, "Invalid command, only one control command can be executed each time"}, {ERR_KMSG_SWITCH_VALUE_INVALID, "Invalid kmsg switch value, valid:on/off"} }; - +static bool g_infoWait = false; +static bool g_lastPck = false; +const int LENGTH_DEFAULT = 20; +const int LENGTH_HEX = 18; +const int LENGTH_TEMP = 100; +const int LENGHT_PRECISE = 2; string ParseErrorCode(ErrorCode errorCode) { if (errorMsg.count(errorCode) == 0) { @@ -145,27 +153,31 @@ string GetPressAlgStr(uint16_t pressAlg) return pressAlgStr; } -string GetByteLenStr(uint64_t buffSize) +string GetByteLenPrecise(uint64_t buffSize, uint32_t precise) { string buffSizeStr; if (buffSize < ONE_KB) { buffSizeStr += to_string(buffSize); buffSizeStr += "B"; } else if (buffSize < ONE_MB) { - buffSize = buffSize / ONE_KB; - buffSizeStr += to_string(buffSize); + std::ostringstream oss; + oss << setiosflags(ios::fixed) << setprecision(precise) << std::fixed << (double)buffSize / ONE_KB; + buffSizeStr += oss.str(); buffSizeStr += "K"; } else if (buffSize < ONE_GB) { - buffSize = buffSize / ONE_MB; - buffSizeStr += to_string(buffSize); + std::ostringstream oss; + oss << setiosflags(ios::fixed) << setprecision(precise) << std::fixed << (double)buffSize / ONE_MB; + buffSizeStr += oss.str(); buffSizeStr += "M"; } else if (buffSize < ONE_TB) { - buffSize = buffSize / ONE_GB; - buffSizeStr += to_string(buffSize); + std::ostringstream oss; + oss << setiosflags(ios::fixed) << setprecision(precise) << std::fixed << (double)buffSize / ONE_GB; + buffSizeStr += oss.str(); buffSizeStr += "G"; } else { - buffSize = buffSize / ONE_TB; - buffSizeStr += to_string(buffSize); + std::ostringstream oss; + oss << setiosflags(ios::fixed) << setprecision(precise) << std::fixed << (double)buffSize / ONE_TB; + buffSizeStr += oss.str(); buffSizeStr += "T"; } return buffSizeStr; @@ -197,7 +209,7 @@ int32_t ControlCmdResult(const char* message) } else { outputStr += GetLogTypeStr(pBuffSizeRst->logType); outputStr += " buffer size is "; - outputStr += GetByteLenStr(pBuffSizeRst->buffSize); + outputStr += GetByteLenPrecise(pBuffSizeRst->buffSize, 0); outputStr += "\n"; } pBuffSizeRst++; @@ -220,7 +232,7 @@ int32_t ControlCmdResult(const char* message) } else { outputStr += GetLogTypeStr(pBuffResizeRst->logType); outputStr += " buffer size is "; - outputStr += GetByteLenStr(pBuffResizeRst->buffSize); + outputStr += GetByteLenPrecise(pBuffResizeRst->buffSize, 0); outputStr += "\n"; } pBuffResizeRst++; @@ -228,53 +240,98 @@ int32_t ControlCmdResult(const char* message) } break; } - case MC_RSP_STATISTIC_INFO_QUERY: { + case MC_RSP_STATISTIC_INFO_WAIT: { StatisticInfoQueryResponse* staInfoQueryRsp = (StatisticInfoQueryResponse*)message; - string logOrDomain; + StatisticInfoResult* infoRst = (StatisticInfoResult*)staInfoQueryRsp->statisticInfoRst; if (!staInfoQueryRsp) { return RET_FAIL; } - if (staInfoQueryRsp->domain != 0xffffffff) { - logOrDomain = to_string(staInfoQueryRsp->domain); - } else { - logOrDomain = GetLogTypeStr(staInfoQueryRsp->logType); + std::ostringstream oss; + char tmp[LENGTH_TEMP] = {}; + time_t ts = infoRst->tv_sec; + struct tm* tm = localtime(&ts); + strftime(tmp, LENGTH_TEMP, "%Y-%m-%d %H:%M:%S", tm); + if (!g_infoWait) { + g_infoWait = true; + std::cout << "Statistic begin at: " << tmp << std::endl; + oss << std::left << std::setw(LENGTH_DEFAULT) << "TYPE" << std::setw(LENGTH_DEFAULT) << "DOMAINID" + << std::setw(LENGTH_DEFAULT) << "DOMAINNAME" << std::setw(LENGTH_DEFAULT) << "PRINTED" + << std::setw(LENGTH_DEFAULT) << "CACHED" << std::setw(LENGTH_DEFAULT) << "DROPPED" << std::endl; } - if (staInfoQueryRsp->result == RET_SUCCESS) { - outputStr += logOrDomain; - outputStr += " print log length is "; - outputStr += GetByteLenStr(staInfoQueryRsp->printLen); - outputStr += "\n"; - outputStr += logOrDomain; - outputStr += " cache log length is "; - outputStr += GetByteLenStr(staInfoQueryRsp->cacheLen); - outputStr += "\n"; - outputStr += logOrDomain; - outputStr += " dropped log lines is "; - outputStr += GetByteLenStr(staInfoQueryRsp->dropped); - } else if (staInfoQueryRsp->result < 0) { - outputStr += logOrDomain; - outputStr += " statistic info query fail\n"; - outputStr += ParseErrorCode((ErrorCode)staInfoQueryRsp->result); + while (infoRst && resultLen < msgLen) { + oss << std::left << std::setw(LENGTH_DEFAULT) << GetLogTypeStr(infoRst->logType) + << "0x" << std::setw(LENGTH_HEX) << hex << infoRst->domain << std::setw(LENGTH_DEFAULT) << "" + << std::setw(LENGTH_DEFAULT) << GetByteLenPrecise(infoRst->printLen, LENGHT_PRECISE) + << std::setw(LENGTH_DEFAULT) << GetByteLenPrecise(infoRst->cacheLen, LENGHT_PRECISE) + << std::setw(LENGTH_DEFAULT) << to_string(infoRst->dropped) + "lines" << std::endl; + infoRst++; + resultLen += sizeof(StatisticInfoResult); } + std::cout << oss.str(); break; } - case MC_RSP_STATISTIC_INFO_CLEAR: { - StatisticInfoClearResponse* staInfoClearRsp = (StatisticInfoClearResponse*)message; - string logOrDomain; - if (!staInfoClearRsp) { + case MC_RSP_STATISTIC_INFO_QUERY: { + StatisticInfoQueryResponse* staInfoQueryRsp = (StatisticInfoQueryResponse*)message; + StatisticInfoResult* infoRst = (StatisticInfoResult*)staInfoQueryRsp->statisticInfoRst; + if (!staInfoQueryRsp) { return RET_FAIL; } - if (staInfoClearRsp->domain != 0xffffffff) { - logOrDomain = to_string(staInfoClearRsp->domain); + std::ostringstream oss; + char tmp[LENGTH_TEMP] = {}; + time_t ts = infoRst->tv_sec; + struct tm* tm = localtime(&ts); + strftime(tmp, LENGTH_TEMP, "%Y-%m-%d %H:%M:%S", tm); + if (g_infoWait) { + g_lastPck = true; + } + if (!g_lastPck) { + std::cout << "Statistic begin at: " << tmp << std::endl; + } + if (infoRst->logType == TYPE_ALL) { + oss << std::left << std::setw(LENGTH_DEFAULT) << "DOMAINID" << std::setw(LENGTH_DEFAULT) + << "DOMAINNAME" << std::setw(LENGTH_DEFAULT) << "PRINTED" << std::setw(LENGTH_DEFAULT) + << "CACHED" << std::setw(LENGTH_DEFAULT) << "DROPPED" << std::endl << "0x" << std::setw(LENGTH_HEX) + << hex << infoRst->domain << std::setw(LENGTH_DEFAULT) << ""; + } else if (infoRst->domain == DOMAIN_ALL) { + oss << std::left << std::setw(LENGTH_DEFAULT) << "TYPE" << std::setw(LENGTH_DEFAULT) << "PRINTED" + << std::setw(LENGTH_DEFAULT) << "CACHED" << std::setw(LENGTH_DEFAULT) << "DROPPED" << std::endl + << std::setw(LENGTH_DEFAULT) << GetLogTypeStr(infoRst->logType); } else { - logOrDomain = GetLogTypeStr(staInfoClearRsp->logType); + if (!g_lastPck) { + oss << std::left << std::setw(LENGTH_DEFAULT) << "TYPE" << std::setw(LENGTH_DEFAULT) << "DOMAINID" + << std::setw(LENGTH_DEFAULT) << "DOMAINNAME" << std::setw(LENGTH_DEFAULT) << "PRINTED" + << std::setw(LENGTH_DEFAULT) << "CACHED" << std::setw(LENGTH_DEFAULT) + << "DROPPED" << std::endl; + } + while (infoRst && resultLen < msgLen) { + oss << std::left << std::setw(LENGTH_DEFAULT) << GetLogTypeStr(infoRst->logType) << "0x" + << std::setw(LENGTH_HEX) << hex << infoRst->domain << std::setw(LENGTH_DEFAULT) + << "" << std::setw(LENGTH_DEFAULT) << GetByteLenPrecise(infoRst->printLen, LENGHT_PRECISE) + << std::setw(LENGTH_DEFAULT) << GetByteLenPrecise(infoRst->cacheLen, LENGHT_PRECISE) + << std::setw(LENGTH_DEFAULT) << to_string(infoRst->dropped) + "lines" << std::endl;; + infoRst++; + resultLen += sizeof(StatisticInfoResult); + } + std::cout << oss.str(); + break; + } + if (infoRst->result == RET_SUCCESS) { + oss << setw(LENGTH_DEFAULT) << GetByteLenPrecise(infoRst->printLen, LENGHT_PRECISE) + << setw(LENGTH_DEFAULT) << GetByteLenPrecise(infoRst->cacheLen, LENGHT_PRECISE) + << setw(LENGTH_DEFAULT) << to_string(infoRst->dropped) + "lines" << std::endl; + std::cout << oss.str(); + } else if (infoRst->result < 0) { + outputStr += "Statistic Info Query Failed\n"; + outputStr += ParseErrorCode((ErrorCode)infoRst->result); } + break; + } + case MC_RSP_STATISTIC_INFO_CLEAR: { + StatisticInfoClearResponse* staInfoClearRsp = (StatisticInfoClearResponse*)message; if (staInfoClearRsp->result == RET_SUCCESS) { - outputStr += logOrDomain; - outputStr += " statistic info clear success "; + outputStr += "Statistic Info Clear Success\n"; } else if (staInfoClearRsp->result < 0) { - outputStr += logOrDomain; - outputStr += " statistic info clear fail\n"; + outputStr += "Statistic Info Clear Failed\n"; outputStr += ParseErrorCode((ErrorCode)staInfoClearRsp->result); } break; @@ -293,8 +350,7 @@ int32_t ControlCmdResult(const char* message) outputStr += "\n"; } else { outputStr += GetLogTypeStr(pLogClearRst->logType); - outputStr += " log clear success "; - outputStr += "\n"; + outputStr += " log clear success\n"; } pLogClearRst++; resultLen += sizeof(LogClearResult); @@ -381,7 +437,7 @@ int32_t ControlCmdResult(const char* message) default: break; } - cout << outputStr << endl; + cout << outputStr; return 0; } diff --git a/services/hilogtool/main.cpp b/services/hilogtool/main.cpp index d35e9208efb3d16aa5aafd4740487614afad926a..474ee06cc0ba9593d3a9022810437f804a3f92d8 100644 --- a/services/hilogtool/main.cpp +++ b/services/hilogtool/main.cpp @@ -614,7 +614,9 @@ int HilogEntry(int argc, char* argv[]) ControlCmdResult(recvBuffer); break; } - + case MC_RSP_STATISTIC_INFO_WAIT: + StatisticWaitOp(controller, recvBuffer, RECV_BUF_LEN); + break; case LOG_QUERY_RESPONSE: { LogQueryResponseOp(controller, recvBuffer, RECV_BUF_LEN, &context, showFormat);