diff --git a/adapter/properties.cpp b/adapter/properties.cpp index 939b0ea34b062c20073e4ca70b1ca05c2b662b3c..da2acb72ee40b0efba6b92b3c8b952f3a37c7b0e 100644 --- a/adapter/properties.cpp +++ b/adapter/properties.cpp @@ -47,6 +47,7 @@ static pthread_mutex_t g_persistDebugLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_privateLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_processFlowLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_domainFlowLock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t g_kmsgLock = PTHREAD_MUTEX_INITIALIZER; using PropertyCache = struct { const void* pinfo; @@ -115,6 +116,9 @@ string GetPropertyName(uint32_t propType) case PROP_SINGLE_DEBUG: key = "hilog.debug.on"; break; + case PROP_KMSG: + key = "persist.sys.hilog.kmsg.on"; + break; case PROP_PERSIST_DEBUG: key = "persist.sys.hilog.debug.on"; break; @@ -141,6 +145,8 @@ static int LockByProp(uint32_t propType) return pthread_mutex_trylock(&g_tagLevelLock); case PROP_SINGLE_DEBUG: return pthread_mutex_trylock(&g_debugLock); + case PROP_KMSG: + return pthread_mutex_trylock(&g_kmsgLock); case PROP_PERSIST_DEBUG: return pthread_mutex_trylock(&g_persistDebugLock); default: @@ -172,6 +178,9 @@ static void UnlockByProp(uint32_t propType) case PROP_SINGLE_DEBUG: pthread_mutex_unlock(&g_debugLock); break; + case PROP_KMSG: + pthread_mutex_unlock(&g_kmsgLock); + break; case PROP_PERSIST_DEBUG: pthread_mutex_unlock(&g_persistDebugLock); break; @@ -271,6 +280,14 @@ bool IsDomainSwitchOn() return GetSwitchCache(isFirst, *switchCache, PROP_DOMAIN_FLOWCTRL, false); } +bool IsKmsgSwitchOn() +{ + static SwitchCache* switchCache = new SwitchCache {{nullptr, 0xffffffff, ""}, false}; + static atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; + bool isFirst = !isFirstFlag.test_and_set(); + return GetSwitchCache(isFirst, *switchCache, PROP_KMSG, false); +} + static uint16_t GetCacheLevel(char propertyChar) { uint16_t cacheLevel = LOG_LEVEL_MIN; @@ -394,4 +411,4 @@ uint16_t GetTagLevel(const string& tag) return it->second->logLevel; } } -} \ No newline at end of file +} diff --git a/adapter/properties.h b/adapter/properties.h index cebbaa193af0ecdd55d7bffdbf5d18deefea87d0..12d2e5d075fa3a7e1266b492f081dd91ed400bd6 100644 --- a/adapter/properties.h +++ b/adapter/properties.h @@ -30,6 +30,7 @@ using PropType = enum { PROP_DOMAIN_LOG_LEVEL, PROP_TAG_LOG_LEVEL, PROP_SINGLE_DEBUG, + PROP_KMSG, PROP_PERSIST_DEBUG, }; @@ -44,6 +45,7 @@ bool IsPersistDebugOn(); bool IsPrivateSwitchOn(); bool IsProcessSwitchOn(); bool IsDomainSwitchOn(); +bool IsKmsgSwitchOn(); uint16_t GetGlobalLevel(); uint16_t GetDomainLevel(uint32_t domain); diff --git a/frameworks/native/format.cpp b/frameworks/native/format.cpp index fd675c416ceafb05b3a175f1cb6c7b5026d359b4..476620b1972892982c793414dd5383ac00b0adc8 100644 --- a/frameworks/native/format.cpp +++ b/frameworks/native/format.cpp @@ -31,9 +31,6 @@ static const int HILOG_COLOR_GREEN = 40; static const int HILOG_COLOR_ORANGE = 166; static const int HILOG_COLOR_RED = 196; static const int HILOG_COLOR_YELLOW = 226; -static const long long NS = 1000000000LL; -static const long long NS2US = 1000LL; -static const long long NS2MS = 1000000LL; const char* ParsedFromLevel(uint16_t level) { @@ -67,7 +64,7 @@ int HilogShowTimeBuffer(char* buffer, int bufLen, uint32_t showFormat, struct tm* ptm = nullptr; size_t timeLen = 0; int ret = 0; - nsecTime = (now < 0) ? (NS - nsecTime) : nsecTime; + nsecTime = (now < 0) ? (NSEC - nsecTime) : nsecTime; if ((showFormat & (1 << EPOCH_SHOWFORMAT)) || (showFormat & (1 << MONOTONIC_SHOWFORMAT))) { ret = snprintf_s(buffer, bufLen, bufLen - 1, diff --git a/frameworks/native/include/hilog_common.h b/frameworks/native/include/hilog_common.h index 1ab205eb7bb4fd5b236c45cd6fa4c957b8307e23..a022c71ab3783f8932a998725beba04d7f1f34f8 100644 --- a/frameworks/native/include/hilog_common.h +++ b/frameworks/native/include/hilog_common.h @@ -17,6 +17,7 @@ #define HILOG_COMMON_H #include +#include #ifdef HILOG_USE_MUSL #define SOCKET_FILE_DIR "/dev/unix/socket/" @@ -44,11 +45,15 @@ #define ONE_MB (1UL<<20) #define ONE_GB (1UL<<30) #define ONE_TB (1ULL<<40) - +const long long NSEC = 1000000000LL; +const long long US = 1000000LL; +const long long NS2US = 1000LL; +const long long NS2MS = 1000000LL; const uint32_t MAX_BUFFER_SIZE = 1UL<<30; const uint32_t MAX_PERSISTER_BUFFER_SIZE = 64 * 1024; const int MSG_MAX_LEN = 2048; - +constexpr uint64_t PRIME = 0x100000001B3ull; +constexpr uint64_t BASIS = 0xCBF29CE484222325ull; /* * header of log message from libhilog to hilogd */ @@ -123,5 +128,18 @@ typedef enum { ERR_BUFF_SIZE_INVALID = -30, ERR_COMMAND_INVALID = -31, ERR_LOG_PERSIST_TASK_FAIL = -32, + ERR_KMSG_SWITCH_VALUE_INVALID = -33, } ErrorCode; + +class HilogMsgWrapper { +public: + explicit HilogMsgWrapper(const std::vector & _msgBuffer) : msgBuffer(_msgBuffer) {}; + explicit HilogMsgWrapper(std::vector && _msgBuffer) { std::swap(msgBuffer, _msgBuffer); } + HilogMsg& getHilogMsg() { return *reinterpret_cast(msgBuffer.data()); } + bool IsValid() { return validity; } + void SetInvalid() { validity = false; } +private: + std::vector msgBuffer; + bool validity = true; +}; #endif /* HILOG_COMMON_H */ diff --git a/frameworks/native/include/hilog_input_socket_server.h b/frameworks/native/include/hilog_input_socket_server.h index 7a451f303792dece1643c8d8be83996c2c280a64..c8f7200cf40d9109847340aa79a1d090f698c761 100644 --- a/frameworks/native/include/hilog_input_socket_server.h +++ b/frameworks/native/include/hilog_input_socket_server.h @@ -28,6 +28,7 @@ namespace HiviewDFX { class HilogInputSocketServer : public DgramSocketServer { public: + #ifndef __RECV_MSG_WITH_UCRED_ using HandlingFunc = std::function& data)>; #else diff --git a/frameworks/native/include/hilogtool_msg.h b/frameworks/native/include/hilogtool_msg.h index bf3b9f9184f8c9ace1e270a259de2f05c1426fee..1123a5f3c7dda2d47c4126e2bfa59a51978ee181 100644 --- a/frameworks/native/include/hilogtool_msg.h +++ b/frameworks/native/include/hilogtool_msg.h @@ -55,6 +55,7 @@ typedef enum { */ typedef enum { OT_PRIVATE_SWITCH = 0x01, + OT_KMSG_SWITCH, OT_LOG_LEVEL, OT_FLOW_SWITCH, } OperateType; @@ -310,6 +311,7 @@ typedef struct { typedef struct { std::string privateSwitchStr; + std::string kmsgSwitchStr; std::string flowSwitchStr; std::string logLevelStr; std::string domainStr; diff --git a/interfaces/native/innerkits/include/hilog/log_c.h b/interfaces/native/innerkits/include/hilog/log_c.h index 5622eaaad15a03e76911cefaaf031ca52a35e325..a32b3ed5a076d83e367a6d427e0683ab49c5e5c6 100644 --- a/interfaces/native/innerkits/include/hilog/log_c.h +++ b/interfaces/native/innerkits/include/hilog/log_c.h @@ -1,17 +1,17 @@ -/* - * 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. - */ +/* + * 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 HIVIEWDFX_HILOG_C_H #define HIVIEWDFX_HILOG_C_H @@ -37,10 +37,10 @@ extern "C" { typedef enum { LOG_TYPE_MIN = 0, LOG_APP = 0, - // Log to kmsg, only used by init phase. LOG_INIT = 1, // Used by core service, framework. LOG_CORE = 3, + LOG_KMSG = 4, LOG_TYPE_MAX } LogType; diff --git a/services/hilogd/BUILD.gn b/services/hilogd/BUILD.gn index e241cd5b412b2c1dfe5268366cf5e3c96d3bb6fe..ac94a2950ec2bcb64f6d0a509d15ac04f5d2ab43 100644 --- a/services/hilogd/BUILD.gn +++ b/services/hilogd/BUILD.gn @@ -16,16 +16,18 @@ import("//build/ohos.gni") config("hilogd_config") { visibility = [ ":*" ] - include_dirs = [ "include" ] + include_dirs = [ "include","//base/startup/init_lite/interfaces/innerkits/include" ] } ohos_executable("hilogd") { sources = [ "cmd_executor.cpp", "flow_control_init.cpp", + "kmsg_parser.cpp", "log_buffer.cpp", "log_collector.cpp", "log_compress.cpp", + "log_kmsg.cpp", "log_persister.cpp", "log_persister_rotator.cpp", "log_querier.cpp", @@ -40,6 +42,7 @@ ohos_executable("hilogd") { "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", "//third_party/zlib:libz", "//utils/native/base:utilsecurec_shared", + "//base/startup/init_lite/interfaces/innerkits/file:libfile", ] deps += [ "etc:hilogd_etc" ] diff --git a/services/hilogd/cmd_executor.cpp b/services/hilogd/cmd_executor.cpp index 86946fa825b9f5604506e370fa4c6548d90e6e61..9de8c6fac6fb3cd403e509abc3f6736b401f8568 100644 --- a/services/hilogd/cmd_executor.cpp +++ b/services/hilogd/cmd_executor.cpp @@ -28,26 +28,10 @@ namespace HiviewDFX { const int MAX_WRITE_LOG_TASK = 100; using namespace std; -HilogBuffer* CmdExecutor::hilogBuffer = nullptr; -void LogQuerierMonitor(std::unique_ptr handler) +CmdExecutor::CmdExecutor(HilogBuffer& buffer) { - prctl(PR_SET_NAME, "hilogd.query"); - std::shared_ptr logQuerier = std::make_shared(std::move(handler), - CmdExecutor::getHilogBuffer()); - logQuerier->LogQuerierThreadFunc(logQuerier); -} - -int CmdExecutorThreadFunc(std::unique_ptr handler) -{ - std::thread logQuerierMonitorThread(LogQuerierMonitor, std::move(handler)); - logQuerierMonitorThread.detach(); - return 0; -} - -CmdExecutor::CmdExecutor(HilogBuffer* buffer) -{ - hilogBuffer = buffer; + hilogBuffer = &buffer; } void CmdExecutor::StartCmdExecutorThread() @@ -60,7 +44,13 @@ void CmdExecutor::StartCmdExecutorThread() cout << "chmod control socket failed !\n"; } cout << "Begin to cmd accept !\n"; - cmdExecutorMainSocket.AcceptConnection(CmdExecutorThreadFunc); + cmdExecutorMainSocket.AcceptConnection([](std::unique_ptr handler) { + prctl(PR_SET_NAME, "hilogd.query"); + std::shared_ptr logQuerier = std::make_shared(std::move(handler), + CmdExecutor::getHilogBuffer()); + logQuerier->LogQuerierThreadFunc(logQuerier); + return 0; + }); } } diff --git a/services/hilogd/etc/hilog_domains.conf b/services/hilogd/etc/hilog_domains.conf old mode 100644 new mode 100755 diff --git a/services/hilogd/etc/hilogd.cfg b/services/hilogd/etc/hilogd.cfg old mode 100644 new mode 100755 index e5516f34463e0f81c40dad5384995300ce3824ab..becec9001d04f0ebd24e5df200bb5308a1065980 --- a/services/hilogd/etc/hilogd.cfg +++ b/services/hilogd/etc/hilogd.cfg @@ -19,10 +19,11 @@ "disabled" : 1, "uid" : "logd", "gid" : "log", + "file" : ["/dev/kmsg rd 0640 root root"], "socket" : [ "hilogInput dgram 0666 logd logd passcred", "hilogControl seqpacket 0600 logd logd false" ] } ] -} \ No newline at end of file +} diff --git a/services/hilogd/include/cmd_executor.h b/services/hilogd/include/cmd_executor.h index 8a3573aeacbc2849918166e4bfe60cde6d6d5678..bbb8a0c83b77b7f9adb9c737e3015595cd8517f6 100644 --- a/services/hilogd/include/cmd_executor.h +++ b/services/hilogd/include/cmd_executor.h @@ -26,12 +26,13 @@ namespace OHOS { namespace HiviewDFX { class CmdExecutor { public: - CmdExecutor(HilogBuffer* buffer); + CmdExecutor(HilogBuffer& buffer); + CmdExecutor(HilogBuffer &&) = delete; void StartCmdExecutorThread(); static HilogBuffer* getHilogBuffer(); ~CmdExecutor() = default; private: - static HilogBuffer* hilogBuffer; + inline static HilogBuffer* hilogBuffer = nullptr; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/services/hilogd/include/kmsg_parser.h b/services/hilogd/include/kmsg_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..b475e553274cf3fd2e6f3cc63130bbaa35b7ceb1 --- /dev/null +++ b/services/hilogd/include/kmsg_parser.h @@ -0,0 +1,30 @@ +/* + * 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 KMSG_PARSER_H +#define KMSG_PARSER_H + +#include "log_collector.h" + +namespace OHOS { +namespace HiviewDFX { +class KmsgParser { +public: + HilogMsgWrapper ParseKmsg(std::vector& kmsgBuffer); + std::chrono::time_point BootTime(); +}; +} // namespace HiviewDFX +} // namespace OHOS +#endif + diff --git a/services/hilogd/include/log_buffer.h b/services/hilogd/include/log_buffer.h index a0ad2ddd411cfd4c00602a320838211db9e5717c..5dd12f96637bc32283ba9d7b7145b16e5ccb618f 100644 --- a/services/hilogd/include/log_buffer.h +++ b/services/hilogd/include/log_buffer.h @@ -53,6 +53,7 @@ private: size_t size; size_t sizeByType[LOG_TYPE_MAX]; std::list hilogDataList; + std::list hilogKlogList; std::shared_mutex hilogBufferMutex; std::map cacheLenByDomain; std::map printLenByDomain; diff --git a/services/hilogd/include/log_collector.h b/services/hilogd/include/log_collector.h index 79889045deff41b9919063408b84c4267d2c81dd..3c7f0bcb69df5e1d45f5bcd5f8e9d1aafedd45ed 100644 --- a/services/hilogd/include/log_collector.h +++ b/services/hilogd/include/log_collector.h @@ -23,7 +23,8 @@ namespace OHOS { namespace HiviewDFX { class LogCollector { public: - LogCollector(HilogBuffer* buffer); + LogCollector(HilogBuffer &buffer) : m_hilogBuffer(buffer) {} + LogCollector(HilogBuffer &&) = delete; void InsertDropInfo(const HilogMsg &msg, int droppedCount); size_t InsertLogToBuffer(const HilogMsg& msg); #ifndef __RECV_MSG_WITH_UCRED_ @@ -33,8 +34,8 @@ public: #endif ~LogCollector() = default; private: - HilogBuffer* m_hilogBuffer = nullptr; + HilogBuffer& m_hilogBuffer; }; } // namespace HiviewDFX } // namespace OHOS -#endif \ No newline at end of file +#endif diff --git a/services/hilogd/include/log_kmsg.h b/services/hilogd/include/log_kmsg.h new file mode 100644 index 0000000000000000000000000000000000000000..a911e8f1c3b9a1384a7772d21423e0750e4d69f0 --- /dev/null +++ b/services/hilogd/include/log_kmsg.h @@ -0,0 +1,39 @@ +/* + * 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_KMSG_H +#define LOG_KMSG_H + +#include "log_buffer.h" +#include "kmsg_parser.h" + +namespace OHOS { +namespace HiviewDFX { +class LogKmsg { +public: + LogKmsg(HilogBuffer& hilogBuffer) : hilogBuffer(hilogBuffer) {}; + LogKmsg(HilogBuffer&&) = delete; + ~LogKmsg(); + ssize_t LinuxReadOneKmsg(KmsgParser& parser); + int LinuxReadAllKmsg(); + void ReadAllKmsg(); + void Start(); +private: + int kmsgCtl = -1; + HilogBuffer& hilogBuffer; +}; +} // namespace HiviewDFX +} // namespace OHOS +#endif + diff --git a/services/hilogd/kmsg_parser.cpp b/services/hilogd/kmsg_parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..774045e34ad760a124569fc2f4ea49f88cfc616c --- /dev/null +++ b/services/hilogd/kmsg_parser.cpp @@ -0,0 +1,186 @@ +/* + * 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 "kmsg_parser.h" +#include "hilog/log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace HiviewDFX { +using namespace std; +using namespace std::chrono; + +constexpr int DEC = 10; + +// Avoid name collision between sys/syslog.h and our log_c.h +#undef LOG_FATAL +#undef LOG_ERR +#undef LOG_WARN +#undef LOG_INFO +#undef LOG_DEBUG + +void ParseHeader(std::string& str, uint16_t* level, uint64_t* timestamp) +{ + static const std::string pattern = "(\\d+),(\\d+),(\\d+),(\\S);"; + static const std::regex express(pattern); + std::match_results res; + if (std::regex_search(str.begin(), str.end(), res, express)) { + *level = strtoul(res[1].str().c_str(), nullptr, DEC); + *timestamp = strtoumax(res[3].str().c_str(), nullptr, DEC); + str = res.suffix(); + } +} + +// Parse pid if exists +uint32_t ParsePid(std::string& str) +{ + static const std::string pattern = "\\[pid=(\\d+)\\]"; + static const std::regex express(pattern); + std::match_results res; + if (std::regex_search(str.begin(), str.end(), res, express)) { + str = res.suffix(); + return strtoumax(res[1].str().c_str(), nullptr, DEC); + } + return 0; +} + +std::string ParseTag(std::string& str) +{ + static const std::string pattern = "\\[.*?\\]"; + static const std::regex express(pattern); + std::match_results res; + if (std::regex_search(str.begin(), str.end(), res, express)) { + std::string ret = res[0].str(); + str = res.suffix().str(); + return ret; + } + return ""; +} + +// Log levels are different in syslog.h and hilog log_c.h +uint16_t KmsgLevelMap(uint16_t prio) +{ + uint16_t level; + switch (prio) { + case 0: + case 1: + case 2: + level = LOG_FATAL; + break; + case 3: + level = LOG_ERROR; + break; + case 4: + case 5: + level = LOG_WARN; + break; + case 6: + level = LOG_INFO; + break; + default: + level = LOG_DEBUG; + break; + } + return level; +} + +constexpr timespec TimepointToTimespec(time_point tp) +{ + auto secs = time_point_cast(tp); + auto nsecs = time_point_cast(tp) - time_point_cast(secs); + return timespec{secs.time_since_epoch().count(), nsecs.count()}; +} + +// Kmsg has microseconds from system boot. Now get the time of system boot. +time_point KmsgParser::BootTime() +{ + struct timespec t_uptime; + clock_gettime(CLOCK_BOOTTIME, &t_uptime); + auto uptime = seconds{t_uptime.tv_sec} + nanoseconds{t_uptime.tv_nsec}; + auto current = system_clock::now(); + auto boottime = current - uptime; + return boottime; +} +HilogMsgWrapper KmsgParser::ParseKmsg(std::vector& kmsgBuffer) +{ + std::string kmsgStr(kmsgBuffer.data()); + std::vector mtag(MAX_TAG_LEN, '\0'); + uint16_t mLevel = 0; + uint64_t timestamp = 0; + ParseHeader(kmsgStr, &mLevel, ×tamp); + // Parses pid if exists. Pid in kmsg content is like: [pid=xxx,...] + uint32_t mpid = 0; + mpid = ParsePid(kmsgStr); + // If there are some other content wrapped in square brackets "[]", parse it as tag + // Otherwise, use default tag "kmsg" + int tagLen = 0; + std::string tagStr = ParseTag(kmsgStr); + if (tagStr != "") { + tagLen = tagStr.size(); + if (strncpy_s(mtag.data(), MAX_TAG_LEN - 1, tagStr.c_str(), tagLen) != 0) { + HilogMsgWrapper nullMsg((std::vector())); + nullMsg.SetInvalid(); + return nullMsg; + } + } else { + char defaultStr[] = "kmsg"; + tagLen = strlen(defaultStr); + if (strncpy_s(mtag.data(), MAX_TAG_LEN - 1, "kmsg", tagLen) != 0) { + HilogMsgWrapper nullMsg((std::vector())); + nullMsg.SetInvalid(); + return nullMsg; + } + } + // Now build HilogMsg and insert it into buffer + int len = kmsgStr.size() + 1; + int msgLen = sizeof(HilogMsg) + tagLen + len + 1; + HilogMsgWrapper msgWrap((std::vector(msgLen, '\0'))); + HilogMsg& msg = msgWrap.getHilogMsg(); + msg.len = msgLen; + msg.tag_len = tagLen + 1; + msg.type = LOG_KMSG; + msg.domain = 0xdfffffff; + msg.level = KmsgLevelMap(mLevel); + time_point logtime = BootTime() + microseconds{timestamp}; + struct timespec logts = TimepointToTimespec(logtime); + msg.tv_sec = logts.tv_sec; + msg.tv_nsec = logts.tv_nsec; + msg.pid = mpid; + msg.tid = mpid; + if (strncpy_s(msg.tag, tagLen + 1, mtag.data(), tagLen) != 0) { + msgWrap.SetInvalid(); + return msgWrap; + } + if (strncpy_s(CONTENT_PTR((&msg)), MAX_LOG_LEN, kmsgStr.c_str(), len) != 0) { + msgWrap.SetInvalid(); + return msgWrap; + } + return msgWrap; +} +} // namespace HiviewDFX +} // namespace OHOS + diff --git a/services/hilogd/log_buffer.cpp b/services/hilogd/log_buffer.cpp index 7a4e68356ffef06eca30dca42505de73a323fc4c..3febc133f0cb6b6cb527e57de571aa11c1abc6cf 100644 --- a/services/hilogd/log_buffer.cpp +++ b/services/hilogd/log_buffer.cpp @@ -15,15 +15,7 @@ #include "log_buffer.h" -#include #include -#include -#include -#include -#include -#include -#include - #include "hilog_common.h" #include "flow_control_init.h" @@ -33,7 +25,7 @@ using namespace std; const float DROP_RATIO = 0.05; static int g_maxBufferSize = 4194304; -static int g_maxBufferSizeByType[LOG_TYPE_MAX] = {1048576, 1048576, 1048576, 1048576}; +static int g_maxBufferSizeByType[LOG_TYPE_MAX] = {1048576, 1048576, 1048576, 1048576, 1048576}; const int DOMAIN_STRICT_MASK = 0xd000000; const int DOMAIN_FUZZY_MASK = 0xdffff; const int DOMAIN_MODULE_BITS = 8; @@ -60,13 +52,14 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) return 0; } + std::list &msgList = (msg.type == LOG_KMSG) ? hilogKlogList : hilogDataList; // Delete old entries when full if (eleSize + sizeByType[msg.type] >= (size_t)g_maxBufferSizeByType[msg.type]) { hilogBufferMutex.lock(); // Drop 5% of maximum log when full - std::list::iterator it = hilogDataList.begin(); + std::list::iterator it = msgList.begin(); while (sizeByType[msg.type] > g_maxBufferSizeByType[msg.type] * (1 - DROP_RATIO) && - it != hilogDataList.end()) { + it != msgList.end()) { if ((*it).type != msg.type) { // Only remove old logs of the same type ++it; continue; @@ -84,7 +77,7 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) size_t cLen = it->len - it->tag_len; size -= cLen; sizeByType[(*it).type] -= cLen; - it = hilogDataList.erase(it); + it = msgList.erase(it); } // Re-confirm if enough elements has been removed @@ -95,13 +88,13 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) } // Insert new log into HilogBuffer - std::list::reverse_iterator rit = hilogDataList.rbegin(); + std::list::reverse_iterator rit = msgList.rbegin(); if (msg.tv_sec >= (rit->tv_sec)) { - hilogDataList.emplace_back(msg); + msgList.emplace_back(msg); } else { // Find the place with right timestamp ++rit; - for (; rit != hilogDataList.rend() && msg.tv_sec < rit->tv_sec; ++rit) { + for (; rit != msgList.rend() && msg.tv_sec < rit->tv_sec; ++rit) { logReaderListMutex.lock_shared(); for (auto &itr :logReaderList) { if (itr.lock()->readPos == std::prev(rit.base())) { @@ -110,7 +103,7 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) } logReaderListMutex.unlock_shared(); } - hilogDataList.emplace(rit.base(), msg); + msgList.emplace(rit.base(), msg); } // Update current size of HilogBuffer size += eleSize; @@ -127,15 +120,17 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) bool HilogBuffer::Query(std::shared_ptr reader) { + uint16_t qTypes = reader->queryCondition.types; + std::list &list = (qTypes == (0b01 << LOG_KMSG)) ? hilogKlogList : hilogDataList; hilogBufferMutex.lock_shared(); if (reader->GetReload()) { - reader->readPos = hilogDataList.begin(); - reader->lastPos = hilogDataList.begin(); + reader->readPos = list.begin(); + reader->lastPos = list.begin(); reader->SetReload(false); } if (reader->isNotified) { - if (reader->readPos == hilogDataList.end()) { + if (reader->readPos == list.end()) { reader->readPos = std::next(reader->lastPos); } } @@ -154,7 +149,7 @@ bool HilogBuffer::Query(std::shared_ptr reader) hilogBufferMutex.unlock_shared(); return true; } - while (reader->readPos != hilogDataList.end()) { + while (reader->readPos != list.end()) { reader->lastPos = reader->readPos; if (ConditionMatch(reader)) { reader->SetSendId(SENDIDA); diff --git a/services/hilogd/log_collector.cpp b/services/hilogd/log_collector.cpp index dfb974a5279a22269999c0ff27b57c802eddbd14..ee69bcbe5eb0b364643da2c2ae599684db44430a 100644 --- a/services/hilogd/log_collector.cpp +++ b/services/hilogd/log_collector.cpp @@ -14,10 +14,12 @@ */ #include "log_collector.h" +#include "log_kmsg.h" #include "flow_control_init.h" #include #include +#include #include #include #include @@ -86,28 +88,24 @@ void LogCollector::onDataRecv(const ucred& cred, std::vector& data) InsertLogToBuffer(*msg); } -LogCollector::LogCollector(HilogBuffer* buffer) : m_hilogBuffer(buffer) -{ -} - size_t LogCollector::InsertLogToBuffer(const HilogMsg& msg) { if (msg.type >= LOG_TYPE_MAX) { return ERR_LOG_TYPE_INVALID; } - size_t result = m_hilogBuffer->Insert(msg); + size_t result = m_hilogBuffer.Insert(msg); if (result <= 0) { return result; } - m_hilogBuffer->logReaderListMutex.lock_shared(); - auto it = m_hilogBuffer->logReaderList.begin(); - while (it != m_hilogBuffer->logReaderList.end()) { + m_hilogBuffer.logReaderListMutex.lock_shared(); + auto it = m_hilogBuffer.logReaderList.begin(); + while (it != m_hilogBuffer.logReaderList.end()) { if ((*it).lock()->GetType() != TYPE_CONTROL) { (*it).lock()->NotifyForNewData(); } ++it; } - m_hilogBuffer->logReaderListMutex.unlock_shared(); + m_hilogBuffer.logReaderListMutex.unlock_shared(); return result; } } // namespace HiviewDFX diff --git a/services/hilogd/log_kmsg.cpp b/services/hilogd/log_kmsg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3517240eceb28b2a10c17454b439b148b6fd8b4f --- /dev/null +++ b/services/hilogd/log_kmsg.cpp @@ -0,0 +1,100 @@ +/* + * 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 "log_kmsg.h" +#include "hilog/log.h" +#include "init_file.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace HiviewDFX { +using namespace std; + +ssize_t LogKmsg::LinuxReadOneKmsg(KmsgParser& parser) +{ + std::vector kmsgBuffer(BUFSIZ, '\0'); + ssize_t size = -1; + do { + size = read(kmsgCtl, kmsgBuffer.data(), BUFSIZ - 1); + } while (size < 0 && errno == EPIPE); + if (size > 0) { + HilogMsgWrapper msgWrap = parser.ParseKmsg(kmsgBuffer); + if (msgWrap.IsValid()) { + size_t result = hilogBuffer.Insert(msgWrap.getHilogMsg()); + if (result <= 0) { + return result; + } + hilogBuffer.logReaderListMutex.lock_shared(); + auto it = hilogBuffer.logReaderList.begin(); + while (it != hilogBuffer.logReaderList.end()) { + if ((*it).lock()->GetType() != TYPE_CONTROL) { + (*it).lock()->NotifyForNewData(); + } + ++it; + } + hilogBuffer.logReaderListMutex.unlock_shared(); + } + } + return size; +} + +int LogKmsg::LinuxReadAllKmsg() +{ + kmsgCtl = GetControlFile("/dev/kmsg"); + if (kmsgCtl < 0) { + std::cout << "Cannot open kmsg! Err=" << strerror(errno) << std::endl; + return -1; + } + std::unique_ptr parser = std::make_unique(); + ssize_t sz = LinuxReadOneKmsg(*parser); + while (sz > 0) { + sz = LinuxReadOneKmsg(*parser); + } + return 1; +} + +void LogKmsg::ReadAllKmsg() +{ +#ifdef __linux__ + std::cout << "Platform: Linux" << std::endl; + LinuxReadAllKmsg(); +#endif +} + +void LogKmsg::Start() +{ + std::thread KmsgThread([this]() { + ReadAllKmsg(); + }); + KmsgThread.join(); +} + +LogKmsg::~LogKmsg() +{ + close(kmsgCtl); +} +} // namespace HiviewDFX +} // namespace OHOS + diff --git a/services/hilogd/log_persister.cpp b/services/hilogd/log_persister.cpp index 6a7e389783f620e7d589bc82e73ba5016fe051e3..74a2eed32b341b75ac274f71d1ebad8dd1aecd92 100644 --- a/services/hilogd/log_persister.cpp +++ b/services/hilogd/log_persister.cpp @@ -321,7 +321,7 @@ int LogPersister::Query(uint16_t logType, list &results) cout << "Persister.Query: logType " << logType << endl; for (auto it = logPersisters.begin(); it != logPersisters.end(); ++it) { cout << "Persister.Query: (*it)->queryCondition.types " - << (*it)->queryCondition.types << endl; + << unsigned((*it)->queryCondition.types) << endl; if (((*it)->queryCondition.types & logType) != 0) { LogPersistQueryResult response; response.logType = (*it)->queryCondition.types; diff --git a/services/hilogd/log_persister_rotator.cpp b/services/hilogd/log_persister_rotator.cpp index 2405ed93cb755901bec5d8c3f1541b3a7efc81a9..28eb850f75a1551664a6331ce67bb64bff753142 100644 --- a/services/hilogd/log_persister_rotator.cpp +++ b/services/hilogd/log_persister_rotator.cpp @@ -25,8 +25,6 @@ namespace OHOS { namespace HiviewDFX { using namespace std; -constexpr uint64_t PRIME = 0x100000001B3ull; -constexpr uint64_t BASIS = 0xCBF29CE484222325ull; uint64_t GetInfoHash(const PersistRecoveryInfo &info) { uint64_t ret {BASIS}; diff --git a/services/hilogd/log_querier.cpp b/services/hilogd/log_querier.cpp index 167bf92b38485fba481670cf108e88b58fbe25e1..482ac2218e4c2976aa0d044bd1364b76e80633a6 100644 --- a/services/hilogd/log_querier.cpp +++ b/services/hilogd/log_querier.cpp @@ -43,7 +43,7 @@ using namespace std; constexpr int MAX_DATA_LEN = 2048; string g_logPersisterDir = HILOG_FILE_DIR; constexpr int DEFAULT_LOG_LEVEL = 1< logReade string logPersisterPath; if (pLogPersistStartRst == nullptr) { return; + } else if (LogTypeForbidden(pLogPersistStartMsg->logType) == false) { + pLogPersistStartRst->result = ERR_QUERY_TYPE_INVALID; } else if (pLogPersistStartMsg->jobId <= 0) { pLogPersistStartRst->result = ERR_LOG_PERSIST_JOBID_INVALID; } else if (pLogPersistStartMsg->fileSize < MAX_PERSISTER_BUFFER_SIZE) { @@ -164,7 +177,9 @@ void HandlePersistStartRequest(char* reqMsg, std::shared_ptr logReade cout << "FileName is not valid!" << endl; pLogPersistStartRst->result = ERR_LOG_PERSIST_FILE_NAME_INVALID; } else { - logPersisterPath = (strlen(pLogPersistStartMsg->filePath) == 0) ? (g_logPersisterDir + "hilog") + string logPersisterFileName = (pLogPersistStartMsg->logType == (0b01 << LOG_KMSG)) ? "hilog_kmsg" : "hilog"; + cout << "logPersisterFileName" << logPersisterFileName << endl; + logPersisterPath = (strlen(pLogPersistStartMsg->filePath) == 0) ? (g_logPersisterDir + logPersisterFileName) : (g_logPersisterDir + string(pLogPersistStartMsg->filePath)); if (strcpy_s(pLogPersistStartMsg->filePath, FILE_PATH_MAX_LEN, logPersisterPath.c_str()) != 0) { pLogPersistStartRst->result = RET_FAIL; @@ -477,6 +492,9 @@ void LogQuerier::LogQuerierThreadFunc(std::shared_ptr logReader) case LOG_QUERY_REQUEST: qRstMsg = (LogQueryRequest*) g_tempBuffer; SetCondition(logReader, *qRstMsg); + if (!LogTypeForbidden(logReader->queryCondition.types)) { + return; + } HandleLogQueryRequest(logReader, *hilogBuffer); break; case NEXT_REQUEST: diff --git a/services/hilogd/main.cpp b/services/hilogd/main.cpp index e95b4dda84a3620b25c06b2123e4245ba14900ef..ad554fae2d076d53beeb7abe0b2f2038d05f7092 100644 --- a/services/hilogd/main.cpp +++ b/services/hilogd/main.cpp @@ -12,18 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include #include #include +#include #include -#include #include "cmd_executor.h" #include "log_querier.h" #include "hilog_input_socket_server.h" #include "log_collector.h" +#include "log_kmsg.h" #include "flow_control_init.h" +#include "properties.h" #ifdef DEBUG #include @@ -41,21 +44,9 @@ constexpr int HILOG_FILE_MASK = 0026; static int g_fd = -1; #endif -static void SigHandler(int sig) +int HilogdEntry() { - if (sig == SIGINT) { -#ifdef DEBUG - if (g_fd > 0) { - close(g_fd); - } -#endif - std::cout<<"Exited!"< hilogBuffer = std::make_unique(); umask(HILOG_FILE_MASK); #ifdef DEBUG int fd = open(HILOG_FILE_DIR"hilogd.txt", O_WRONLY | O_APPEND); @@ -65,22 +56,21 @@ int HilogdEntry(int argc, char* argv[]) std::cout << "open file error:" << strerror(errno) << std::endl; } #endif - std::signal(SIGINT, SigHandler); InitDomainFlowCtrl(); // Start log_collector -#ifndef __RECV_MSG_WITH_UCRED_ + #ifndef __RECV_MSG_WITH_UCRED_ auto onDataReceive = [&hilogBuffer](std::vector& data) { - static LogCollector logCollector(&hilogBuffer); + static LogCollector logCollector(*hilogBuffer); logCollector.onDataRecv(data); }; -#else + #else auto onDataReceive = [&hilogBuffer](const ucred& cred, std::vector& data) { - static LogCollector logCollector(&hilogBuffer); + static LogCollector logCollector(*hilogBuffer); logCollector.onDataRecv(cred, data); }; -#endif + #endif HilogInputSocketServer incomingLogsServer(onDataReceive); if (incomingLogsServer.Init() < 0) { @@ -88,32 +78,32 @@ int HilogdEntry(int argc, char* argv[]) cout << "Failed to init input server socket ! error=" << strerror(errno) << std::endl; #endif } else { - if (chmod(INPUT_SOCKET, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0) { - cout << "chmod input socket failed !\n"; - } #ifdef DEBUG cout << "Begin to listen !\n"; #endif incomingLogsServer.RunServingThread(); } - std::thread startupCheckThread([&hilogBuffer]() { + auto startupCheckTask = std::async(std::launch::async, [&hilogBuffer]() { prctl(PR_SET_NAME, "hilogd.pst_res"); - std::shared_ptr logQuerier = std::make_shared(nullptr, &hilogBuffer); - logQuerier->RestorePersistJobs(hilogBuffer); + std::shared_ptr logQuerier = std::make_shared(nullptr, hilogBuffer.get()); + logQuerier->RestorePersistJobs(*hilogBuffer); }); - startupCheckThread.detach(); - CmdExecutor cmdExecutor(&hilogBuffer); - cmdExecutor.StartCmdExecutorThread(); + auto kmsgTask = std::async(std::launch::async, [&hilogBuffer]() { + LogKmsg logKmsg(*hilogBuffer); + logKmsg.ReadAllKmsg(); + }); + CmdExecutor cmdExecutor(*hilogBuffer); + cmdExecutor.StartCmdExecutorThread(); return 0; } } // namespace HiviewDFX } // namespace OHOS -int main(int argc, char* argv[]) +int main() { - OHOS::HiviewDFX::HilogdEntry(argc, argv); + OHOS::HiviewDFX::HilogdEntry(); return 0; } diff --git a/services/hilogtool/include/hilogtool.h b/services/hilogtool/include/hilogtool.h index 4bcce3af41dd4dec150a6f978826b5f1cfca2dd9..ef74cc97a528e57c2203b8052a4b09f00a991983 100644 --- a/services/hilogtool/include/hilogtool.h +++ b/services/hilogtool/include/hilogtool.h @@ -51,6 +51,7 @@ typedef struct { std::string fileNameArgs; std::string jobIdArgs; std::string personalArgs; + std::string kmsgArgs; std::string logClearArgs; std::string logTypeArgs; std::string domainArgs; diff --git a/services/hilogtool/include/log_controller.h b/services/hilogtool/include/log_controller.h index cc5bb158e935619779b62cd4b76171f1c49aa89c..c9369fca77241f07c9ed79ef801d9b3feeb5b839 100644 --- a/services/hilogtool/include/log_controller.h +++ b/services/hilogtool/include/log_controller.h @@ -30,7 +30,6 @@ constexpr int RECV_BUF_LEN = MAX_LOG_LEN * 2; void SetMsgHead(MessageHeader* msgHeader, const uint8_t msgCmd, const uint16_t msgLen); int MultiQuerySplit(const std::string& src, const char& delim, std::vector& vec); -inline void PrintBuffer(void* pBuff, unsigned int nLen); void NextRequestOp(SeqPacketSocketClient& controller, uint16_t sendId); void LogQueryRequestOp(SeqPacketSocketClient& controller, const HilogArgs* context); void LogQueryResponseOp(SeqPacketSocketClient& controller, char* recvBuffer, uint32_t bufLen, diff --git a/services/hilogtool/log_controller.cpp b/services/hilogtool/log_controller.cpp index 994eec7e7d930d62a5610d8cf849aebc220b5b8f..9419ae9bf065210441dec3f7dd75aca50731cb23 100644 --- a/services/hilogtool/log_controller.cpp +++ b/services/hilogtool/log_controller.cpp @@ -16,12 +16,11 @@ #include "log_controller.h" #include +#include #include #include -#include #include #include -#include #include #include "hilog/log.h" #include "hilog_common.h" @@ -37,7 +36,7 @@ using namespace std; 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) { @@ -82,6 +81,8 @@ uint16_t GetLogType(const string& logTypeStr) logType = LOG_CORE; } else if (logTypeStr == "app") { logType = LOG_APP; + } else if (logTypeStr == "kmsg") { + logType = LOG_KMSG; } else { return 0xffff; } @@ -417,8 +418,13 @@ int32_t LogPersistOp(SeqPacketSocketClient& controller, uint8_t msgCmd, LogPersi } pLogPersistStartMsg->logType = (0b01 << tmpType) | pLogPersistStartMsg->logType; } - pLogPersistStartMsg->jobId = (logPersistParam->jobIdStr == "") ? DEFAULT_JOBID - : stoi(logPersistParam->jobIdStr); + if (pLogPersistStartMsg->logType == (0b01 << LOG_KMSG)) { + pLogPersistStartMsg->jobId = (logPersistParam->jobIdStr == "") ? DEFAULT_KMSG_JOBID : stoi( + logPersistParam->jobIdStr); + } else { + pLogPersistStartMsg->jobId = (logPersistParam->jobIdStr == "") ? DEFAULT_JOBID + : stoi(logPersistParam->jobIdStr); + } if (pLogPersistStartMsg->jobId <= 0) { cout << ParseErrorCode(ERR_LOG_PERSIST_JOBID_INVALID) << endl; return RET_FAIL; @@ -520,7 +526,19 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType return RET_FAIL; } break; - + case OT_KMSG_SWITCH: + key = GetPropertyName(PROP_KMSG); + if (propertyParm->kmsgSwitchStr == "on") { + PropertySet(key.c_str(), "true"); + std::cout << "hilog will store kmsg log" << std::endl; + } else if (propertyParm->kmsgSwitchStr == "off") { + PropertySet(key.c_str(), "false"); + std::cout << "hilog will not store kmsg log" << std::endl; + } else { + std::cout << ParseErrorCode(ERR_KMSG_SWITCH_VALUE_INVALID) << std::endl; + return RET_FAIL; + } + break; case OT_LOG_LEVEL: if (propertyParm->tagStr != "" && propertyParm->domainStr != "") { return RET_FAIL; diff --git a/services/hilogtool/log_display.cpp b/services/hilogtool/log_display.cpp index 59f496e2a8c463a61b6030c898dc271cf636ac5f..2183b52fd4034152c284ec551f4c9f6ee85b1ab9 100644 --- a/services/hilogtool/log_display.cpp +++ b/services/hilogtool/log_display.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -31,16 +30,13 @@ namespace HiviewDFX { using namespace std; using hash_t = std::uint64_t; - -constexpr hash_t PRIME = 0x100000001B3ull; -constexpr hash_t BASIS = 0xCBF29CE484222325ull; - unordered_map errorMsg { {RET_FAIL, "Unexpected error"}, {ERR_LOG_LEVEL_INVALID, "Invalid log level, the valid log levels include D/I/W/E/F"}, - {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init"}, - {ERR_QUERY_TYPE_INVALID, "Query condition on both types and excluded types is undefined"}, + {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init/kmsg"}, + {ERR_QUERY_TYPE_INVALID, "Query condition on both types and excluded types is undefined or\ + queryTypes can not contain app/core/init and kmsg at the same time"}, {ERR_QUERY_LEVEL_INVALID, "Query condition on both levels and excluded levels is undefined"}, {ERR_QUERY_DOMAIN_INVALID, "Invalid domain format, a hexadecimal number is needed"}, {ERR_QUERY_TAG_INVALID, "Query condition on both tags and excluded tags is undefined"}, @@ -69,8 +65,9 @@ unordered_map errorMsg {ERR_FORMAT_INVALID, "Invalid format parameter"}, {ERR_BUFF_SIZE_INVALID, "Invalid buffer size, buffer size should be more than 0 and less than " + to_string(MAX_BUFFER_SIZE)}, - {ERR_COMMAND_INVALID, "Invalid command, only one control command can be executed each time"} -}; + {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"} +}; string ParseErrorCode(ErrorCode errorCode) { @@ -112,6 +109,9 @@ string GetLogTypeStr(uint16_t logType) if (logType == LOG_APP) { logTypeStr = "app"; } + if (logType == LOG_KMSG) { + logTypeStr = "kmsg"; + } return logTypeStr; } @@ -127,6 +127,9 @@ string GetOrigType(uint16_t shiftType) if (((1 << LOG_APP) & shiftType) != 0) { logType += "app,"; } + if (((1 << LOG_KMSG) & shiftType) != 0) { + logType += "kmsg,"; + } logType.erase(logType.end() - 1); return logType; } diff --git a/services/hilogtool/main.cpp b/services/hilogtool/main.cpp index 69867cc372586fccbaf8021b8384f71f6734f93b..f2665d1d660c7ffc278a7e95002d73a4be3e445f 100644 --- a/services/hilogtool/main.cpp +++ b/services/hilogtool/main.cpp @@ -16,12 +16,11 @@ #include #include #include +#include #include #include #include -#include #include -#include #include #include #include @@ -51,6 +50,10 @@ static void Helper() " set privacy formatter feature on or off.\n" " on turn on\n" " off turn off\n" + " -k\n" + " store log type kmsg or not\n" + " on yes\n" + " off no\n" " -s, --statistics query hilogd statistic information.\n" " -S clear hilogd statistic information.\n" " -r remove the logs in hilog buffer, use -t to specify log type\n" @@ -127,6 +130,8 @@ static int GetTypes(HilogArgs context, const string& typesArgs, bool exclude = f types |= 1<