1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "dfx_log.h"
17
18 #include <cstdarg>
19 #include <cstdio>
20 #include <fcntl.h>
21 #include <securec.h>
22 #include <unistd.h>
23
24 #include "dfx_define.h"
25
26 static int g_debugFd = INVALID_FD;
27 static LogLevel g_logLevel = LogLevel::LOG_INFO;
28
29 #ifdef DFX_LOG_DMESG
30 static int g_dmesgFd = INVALID_FD;
31
CloseDmesg()32 static void CloseDmesg()
33 {
34 if (g_dmesgFd > 0) {
35 close(g_dmesgFd);
36 g_dmesgFd = -1;
37 }
38 }
39
LogToDmesg(const LogLevel logLevel,const char * tag,const char * info)40 static void LogToDmesg(const LogLevel logLevel, const char *tag, const char *info)
41 {
42 static const char *LOG_LEVEL_STR[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" };
43 static const char *LOG_KLEVEL_STR[] = { "<7>", "<6>", "<4>", "<3>", "<3>" };
44 int dmesgLevel = static_cast<int>(logLevel) - LOG_DEBUG;
45
46 if (UNLIKELY(g_dmesgFd < 0)) {
47 g_dmesgFd = open("/dev/kmsg", O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
48 }
49 char buf[LOG_BUF_LEN] = {0};
50 if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%s[pid=%d %d][%s][%s]%s",
51 LOG_KLEVEL_STR[dmesgLevel], getpid(), getppid(), tag, LOG_LEVEL_STR[dmesgLevel], info) < 0) {
52 CloseDmesg();
53 return;
54 }
55 if (write(g_dmesgFd, buf, strlen(buf)) < 0) {
56 CloseDmesg();
57 }
58 }
59 #endif
60
InitDebugFd(int fd)61 void InitDebugFd(int fd)
62 {
63 g_debugFd = fd;
64 }
65
CheckDebugLevel(void)66 bool CheckDebugLevel(void)
67 {
68 return LogLevel::LOG_DEBUG >= g_logLevel ? true : false;
69 }
70
SetLogLevel(const LogLevel logLevel)71 void SetLogLevel(const LogLevel logLevel)
72 {
73 g_logLevel = logLevel;
74 }
75
GetLogLevel(void)76 LogLevel GetLogLevel(void)
77 {
78 return g_logLevel;
79 }
80
DfxLogPrint(const LogLevel logLevel,const unsigned int domain,const char * tag,const char * fmt,...)81 int DfxLogPrint(const LogLevel logLevel, const unsigned int domain, const char* tag, const char *fmt, ...)
82 {
83 #ifndef DFX_LOG_UNWIND
84 if (logLevel < g_logLevel) {
85 return -1;
86 }
87 #endif
88
89 va_list args;
90 va_start(args, fmt);
91 int ret = DFXLOG_PRINTV(logLevel, domain, tag, fmt, args);
92 va_end(args);
93 return ret;
94 }
95
DfxLogPrintV(const LogLevel logLevel,const unsigned int domain,const char * tag,const char * fmt,va_list ap)96 int DfxLogPrintV(const LogLevel logLevel, const unsigned int domain, const char* tag, const char *fmt, va_list ap)
97 {
98 if ((logLevel < LogLevel::LOG_DEBUG) || (logLevel > LogLevel::LOG_FATAL)) {
99 return -1;
100 }
101
102 char buf[LOG_BUF_LEN] = {0};
103 int ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, fmt, ap);
104 if (ret == -1) {
105 return ret;
106 }
107 #ifdef DFX_LOG_HILOG_BASE
108 HiLogBasePrint(LOG_CORE, logLevel, domain, tag, "%{public}s", buf);
109 #else
110 HiLogPrint(LOG_CORE, logLevel, domain, tag, "%{public}s", buf);
111 #endif
112
113 #ifdef DFX_LOG_DMESG
114 LogToDmesg(logLevel, tag, buf);
115 #endif
116
117 if (g_debugFd != INVALID_FD) {
118 fprintf(stderr, "%s\n", buf);
119 }
120 return ret;
121 }