From a20dccd08da72f75de4994b30841996655a18a0f Mon Sep 17 00:00:00 2001 From: buzhenwang Date: Tue, 13 Dec 2022 09:29:25 +0800 Subject: [PATCH] hilogBasePrint api adapter to HOS Signed-off-by: buzhenwang --- frameworks/libhilog/BUILD.gn | 1 + frameworks/libhilog/base/hilog_base.cpp | 164 ++++++++++++++++++++---- test/BUILD.gn | 5 +- 3 files changed, 144 insertions(+), 26 deletions(-) diff --git a/frameworks/libhilog/BUILD.gn b/frameworks/libhilog/BUILD.gn index fe1a662..303da9a 100644 --- a/frameworks/libhilog/BUILD.gn +++ b/frameworks/libhilog/BUILD.gn @@ -122,6 +122,7 @@ ohos_source_set("libhilog_base_source") { include_dirs = [ "$vsnprintf_root/include", "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", + "//third_party/bounds_checking_function/include", ] vsnprintf_sources = [ "$vsnprintf_root/vsnprintf_s_p.cpp" ] diff --git a/frameworks/libhilog/base/hilog_base.cpp b/frameworks/libhilog/base/hilog_base.cpp index be974f1..ddc6a07 100644 --- a/frameworks/libhilog/base/hilog_base.cpp +++ b/frameworks/libhilog/base/hilog_base.cpp @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -31,7 +33,10 @@ namespace { constexpr int SOCKET_TYPE = SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC; constexpr int INVALID_SOCKET = -1; -constexpr sockaddr_un SOCKET_ADDR = {AF_UNIX, SOCKET_FILE_DIR INPUT_SOCKET_NAME}; +constexpr size_t HILOG_VEC_MAX_SIZE = 4; +constexpr size_t HILOG_VEC_SIZE_OHCORE = 4; +constexpr size_t HILOG_VEC_SIZE_OH = 3; +constexpr int32_t MAX_DOMAIN_TAGSIZE = 64; struct SocketHandler { std::atomic_int socketFd {INVALID_SOCKET}; @@ -45,12 +50,77 @@ struct SocketHandler { } }; +typedef struct log_time { + uint32_t tv_sec; + uint32_t tv_nsec; +} __attribute__((__packed__)) log_time; + +#define typeof_hw_logging_id_t unsigned char +typedef struct __attribute__((__packed__)) { + typeof_hw_logging_id_t id; + uint16_t tid; + uint16_t ohPid; + log_time realtime; +} hw_log_header_t, HwLogHeader; + +struct HiLogMsgInfo { + HilogMsg *header_; + const char *tag_; + uint16_t tagLen_; + const char *fmt_; + uint16_t fmtLen_; + HiLogMsgInfo(HilogMsg *header, const char *tag, uint16_t tagLen, const char *fmt, uint16_t fmtLen) + { + header_ = header; + tag_ = tag; + tagLen_ = tagLen; + fmt_ = fmt; + fmtLen_ = fmtLen; + } +}; + +typedef enum { + TYPE_OH = 0, + TYPE_OHCORE = 1, +} HiLogProtocolType; + +std::string g_sockPath = SOCKET_FILE_DIR INPUT_SOCKET_NAME; +HiLogProtocolType g_protocolType = TYPE_OH; + +struct Initializer { + Initializer() + { + constexpr char configFile[] = "/system/etc/hilog_config"; + if (access(configFile, F_OK) != 0) { + return; + } + std::ifstream file; + file.open(configFile); + if (file.fail()) { + std::cerr << "open hilog_config config file failed" << std::endl; + return; + } + + std::string sock; + std::string protocol; + file >> sock >> protocol; + if (auto posColon = sock.find(":"); posColon != sock.npos) { + g_sockPath = sock.substr(posColon + 1); + } + if (auto posColon = protocol.find(":"); posColon != protocol.npos) { + g_protocolType = protocol.substr(posColon + 1) == "ohcore" ? TYPE_OHCORE : TYPE_OH; + } + file.close(); + } +}; +Initializer g_initializer; + static int GenerateFD() { - int tmpFd = TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCKET_TYPE, 0)); + int tmpFd = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCKET_TYPE, 0)); int res = tmpFd; if (tmpFd == 0) { - res = TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCKET_TYPE, 0)); + res = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCKET_TYPE, 0)); close(tmpFd); } return res; @@ -65,7 +135,7 @@ static int CheckSocket(SocketHandler& socketHandler) int fd = GenerateFD(); if (fd < 0) { - std::cerr << "Can't get hilog socket! Errno: " << errno << "\n"; + std::cerr << "Can't get hilog socket! Errno: " << errno << std::endl; return fd; } @@ -88,9 +158,11 @@ static int CheckConnection(SocketHandler& socketHandler) if (isConnected) { return 0; } - + sockaddr_un sockAddr = {0}; + sockAddr.sun_family = AF_UNIX; + (void)strcpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), g_sockPath.c_str()); auto result = TEMP_FAILURE_RETRY(connect(socketHandler.socketFd.load(), - reinterpret_cast(&SOCKET_ADDR), sizeof(SOCKET_ADDR))); + reinterpret_cast(&sockAddr), sizeof(sockAddr))); if (result < 0) { std::cerr << "Can't connect to hilog server. Errno: " << errno << "\n"; return result; @@ -99,6 +171,54 @@ static int CheckConnection(SocketHandler& socketHandler) return 0; } +static size_t BuildHilogMessageForOhCore(struct HiLogMsgInfo* logMsgInfo, HwLogHeader& logHeader, uint16_t& logLevel, + char tagBuf[], struct iovec *vec) +{ + struct timespec ts = {0}; + (void)clock_gettime(CLOCK_REALTIME, &ts); + logHeader.realtime.tv_sec = (uint32_t)ts.tv_sec; + logHeader.realtime.tv_nsec = (uint32_t)ts.tv_nsec; + logHeader.tid = (uint32_t)gettid(); + logHeader.ohPid = (uint32_t)getpid(); + logLevel = logMsgInfo->header_->level; + constexpr uint32_t domainFilter = 0x000FFFFF; + if (snprintf_s(tagBuf, MAX_DOMAIN_TAGSIZE, MAX_DOMAIN_TAGSIZE - 1, "%05X/%s", + (logMsgInfo->header_->domain & domainFilter), logMsgInfo->tag_) < 0) { + return 0; + } + + vec[0].iov_base = reinterpret_cast(&logHeader); // 0 : index of hos log header + vec[0].iov_len = sizeof(logHeader); // 0 : index of hos log header + vec[1].iov_base = reinterpret_cast(&logLevel); // 1 : index of log level + vec[1].iov_len = 1; // 1 : index of log level + vec[2].iov_base = reinterpret_cast(const_cast(tagBuf)); // 2 : index of log tag + vec[2].iov_len = strlen(tagBuf) + 1; // 2 : index of log tag + vec[3].iov_base = reinterpret_cast(const_cast(logMsgInfo->fmt_)); // 3 : index of log format + vec[3].iov_len = logMsgInfo->fmtLen_; // 3 : index of log format + return HILOG_VEC_SIZE_OHCORE; +} + +static size_t BuildHilogMessageForOh(struct HiLogMsgInfo* logMsgInfo, struct iovec *vec) +{ + struct timespec ts = {0}; + (void)clock_gettime(CLOCK_REALTIME, &ts); + struct timespec ts_mono = {0}; + (void)clock_gettime(CLOCK_MONOTONIC, &ts_mono); + logMsgInfo->header_->tv_sec = static_cast(ts.tv_sec); + logMsgInfo->header_->tv_nsec = static_cast(ts.tv_nsec); + logMsgInfo->header_->mono_sec = static_cast(ts_mono.tv_sec); + logMsgInfo->header_->len = sizeof(HilogMsg) + logMsgInfo->tagLen_ + logMsgInfo->fmtLen_; + logMsgInfo->header_->tag_len = logMsgInfo->tagLen_; + + vec[0].iov_base = logMsgInfo->header_; // 0 : index of hos log header + vec[0].iov_len = sizeof(HilogMsg); // 0 : index of hos log header + vec[1].iov_base = reinterpret_cast(const_cast(logMsgInfo->tag_)); // 1 : index of log tag + vec[1].iov_len = logMsgInfo->tagLen_; // 1 : index of log tag + vec[2].iov_base = reinterpret_cast(const_cast(logMsgInfo->fmt_)); // 2 : index of log content + vec[2].iov_len = logMsgInfo->fmtLen_; // 2 : index of log content + return HILOG_VEC_SIZE_OH; +} + static int SendMessage(HilogMsg *header, const char *tag, uint16_t tagLen, const char *fmt, uint16_t fmtLen) { SocketHandler socketHandler; @@ -111,25 +231,19 @@ static int SendMessage(HilogMsg *header, const char *tag, uint16_t tagLen, const return ret; } - struct timespec ts = {0}; - (void)clock_gettime(CLOCK_REALTIME, &ts); - struct timespec tsMono = {0}; - (void)clock_gettime(CLOCK_MONOTONIC, &tsMono); - header->tv_sec = static_cast(ts.tv_sec); - header->tv_nsec = static_cast(ts.tv_nsec); - header->mono_sec = static_cast(tsMono.tv_sec); - header->len = sizeof(HilogMsg) + tagLen + fmtLen; - header->tag_len = tagLen; - - std::array vec; - vec[0].iov_base = header; // 0 : index of hos log header - vec[0].iov_len = sizeof(HilogMsg); // 0 : index of hos log header - vec[1].iov_base = reinterpret_cast(const_cast(tag)); // 1 : index of log tag - vec[1].iov_len = tagLen; // 1 : index of log tag - vec[2].iov_base = reinterpret_cast(const_cast(fmt)); // 2 : index of log content - vec[2].iov_len = fmtLen; // 2 : index of log content - ret = TEMP_FAILURE_RETRY(::writev(socketHandler.socketFd.load(), vec.data(), vec.size())); - return ret; + struct iovec vec[HILOG_VEC_MAX_SIZE]; + struct HiLogMsgInfo msgInfo(header, tag, tagLen, fmt, fmtLen); + HwLogHeader logHeader; + uint16_t logLevel = 0; + char tagBuf[MAX_DOMAIN_TAGSIZE] = {0}; + int vecSize = (g_protocolType == TYPE_OHCORE) ? + BuildHilogMessageForOhCore(&msgInfo, logHeader, logLevel, tagBuf, vec) : + BuildHilogMessageForOh(&msgInfo, vec); + if (vecSize <= 0) { + std::cerr << "BuildHilogMessage failed ret = " << vecSize << std::endl; + return RET_FAIL; + } + return TEMP_FAILURE_RETRY(::writev(socketHandler.socketFd.load(), vec, vecSize)); } static int HiLogBasePrintArgs(const LogType type, const LogLevel level, const unsigned int domain, const char *tag, diff --git a/test/BUILD.gn b/test/BUILD.gn index c4f6841..5fef60c 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -29,7 +29,10 @@ ohos_moduletest("HiLogNDKTest") { configs = [ ":module_private_config" ] - deps = [ "//third_party/googletest:gtest_main" ] + deps = [ + "//third_party/bounds_checking_function:libsec_shared", + "//third_party/googletest:gtest_main", + ] external_deps = [ "hilog_native:libhilog", -- Gitee