1 /*
2 * Copyright (c) 2021 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 #include "dfx_log.h"
16
17 #include <cstdarg>
18 #include <cstdio>
19 #include <securec.h>
20 #include <unistd.h>
21
22 #include <faultloggerd_client.h>
23
24 enum class LOG_LEVEL_CLASS {
25 LOG_LEVEL_ALL = 1,
26 LOG_LEVEL_TRACE,
27 LOG_LEVEL_DBG,
28 LOG_LEVEL_INFO,
29 LOG_LEVEL_WARN,
30 LOG_LEVEL_ERR,
31 LOG_LEVEL_FATAL,
32 LOG_LEVEL_OFF
33 };
34
35 static const LOG_LEVEL_CLASS LOG_LEVEL = LOG_LEVEL_CLASS::LOG_LEVEL_INFO;
36 static const int32_t INVALID_FD = -1;
37 static int32_t g_DebugLogFilleDes = INVALID_FD;
38 static const int LOG_BUF_LEN = 1024;
39 #ifndef DFX_LOG_USE_HILOG_BASE
40 static int32_t g_StdErrFilleDes = INVALID_FD;
41 static const OHOS::HiviewDFX::HiLogLabel g_LOG_LABEL = {LOG_CORE, 0xD002D20, "DfxFaultLogger"};
42 #endif
43
DfxLogDebug(const char * format,...)44 int DfxLogDebug(const char *format, ...)
45 {
46 if (LOG_LEVEL_CLASS::LOG_LEVEL_DBG < LOG_LEVEL) {
47 return 0;
48 }
49
50 int ret;
51 char buf[LOG_BUF_LEN] = {0};
52 va_list args;
53 va_start(args, format);
54 ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, args);
55 va_end(args);
56
57 #ifdef DFX_LOG_USE_HILOG_BASE
58 HILOG_BASE_DEBUG(LOG_CORE, "%{public}s", buf);
59 #else
60 OHOS::HiviewDFX::HiLog::Debug(g_LOG_LABEL, "%{public}s", buf);
61 #endif
62
63 if (g_DebugLogFilleDes != INVALID_FD) {
64 fprintf(stderr, "%s\n", buf);
65 }
66 return ret;
67 }
68
DfxLogInfo(const char * format,...)69 int DfxLogInfo(const char *format, ...)
70 {
71 if (LOG_LEVEL_CLASS::LOG_LEVEL_INFO < LOG_LEVEL) {
72 return 0;
73 }
74
75 int ret;
76 char buf[LOG_BUF_LEN] = {0};
77 va_list args;
78 va_start(args, format);
79 ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, args);
80 va_end(args);
81
82 #ifdef DFX_LOG_USE_HILOG_BASE
83 HILOG_BASE_INFO(LOG_CORE, "%{public}s", buf);
84 #else
85 OHOS::HiviewDFX::HiLog::Info(g_LOG_LABEL, "%{public}s", buf);
86 #endif
87
88 if (g_DebugLogFilleDes != INVALID_FD) {
89 fprintf(stderr, "%s\n", buf);
90 }
91 return ret;
92 }
93
DfxLogWarn(const char * format,...)94 int DfxLogWarn(const char *format, ...)
95 {
96 if (LOG_LEVEL_CLASS::LOG_LEVEL_WARN < LOG_LEVEL) {
97 return 0;
98 }
99
100 int ret;
101 char buf[LOG_BUF_LEN] = {0};
102 va_list args;
103 va_start(args, format);
104 ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, args);
105 va_end(args);
106
107 #ifdef DFX_LOG_USE_HILOG_BASE
108 HILOG_BASE_WARN(LOG_CORE, "%{public}s", buf);
109 #else
110 OHOS::HiviewDFX::HiLog::Warn(g_LOG_LABEL, "%{public}s", buf);
111 #endif
112
113 if (g_DebugLogFilleDes != INVALID_FD) {
114 fprintf(stderr, "%s\n", buf);
115 }
116 return ret;
117 }
118
DfxLogError(const char * format,...)119 int DfxLogError(const char *format, ...)
120 {
121 if (LOG_LEVEL_CLASS::LOG_LEVEL_ERR < LOG_LEVEL) {
122 return 0;
123 }
124
125 int ret;
126 char buf[LOG_BUF_LEN] = {0};
127 va_list args;
128 va_start(args, format);
129 ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, args);
130 va_end(args);
131
132 #ifdef DFX_LOG_USE_HILOG_BASE
133 HILOG_BASE_ERROR(LOG_CORE, "%{public}s", buf);
134 #else
135 OHOS::HiviewDFX::HiLog::Error(g_LOG_LABEL, "%{public}s", buf);
136 #endif
137
138 if (g_DebugLogFilleDes != INVALID_FD) {
139 fprintf(stderr, "%s\n", buf);
140 }
141 return ret;
142 }
143
DfxLogFatal(const char * format,...)144 int DfxLogFatal(const char *format, ...)
145 {
146 if (LOG_LEVEL_CLASS::LOG_LEVEL_FATAL < LOG_LEVEL) {
147 return 0;
148 }
149
150 int ret;
151 char buf[LOG_BUF_LEN] = {0};
152 va_list args;
153 va_start(args, format);
154 ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, args);
155 va_end(args);
156
157 #ifdef DFX_LOG_USE_HILOG_BASE
158 HILOG_BASE_FATAL(LOG_CORE, "%{public}s", buf);
159 #else
160 OHOS::HiviewDFX::HiLog::Fatal(g_LOG_LABEL, "%{public}s", buf);
161 #endif
162
163 if (g_DebugLogFilleDes != INVALID_FD) {
164 fprintf(stderr, "%s\n", buf);
165 }
166 return ret;
167 }
168
169 #ifndef DFX_LOG_USE_HILOG_BASE
DfxLogByTrace(bool start,const char * tag)170 void DfxLogByTrace(bool start, const char *tag)
171 {
172 if (start) {
173 StartTrace(BYTRACE_TAG_OHOS, tag);
174 } else {
175 FinishTrace(BYTRACE_TAG_OHOS);
176 }
177 }
178 #endif
179
WriteLog(int32_t fd,const char * format,...)180 int WriteLog(int32_t fd, const char *format, ...)
181 {
182 int ret;
183 char buf[LOG_BUF_LEN] = {0};
184 va_list args;
185 va_start(args, format);
186 ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, args);
187 va_end(args);
188
189 if ((LOG_LEVEL <= LOG_LEVEL_CLASS::LOG_LEVEL_DBG) || (fd == -1)) {
190 #ifdef DFX_LOG_USE_HILOG_BASE
191 HILOG_BASE_DEBUG(LOG_CORE, "%{public}s", buf);
192 #else
193 OHOS::HiviewDFX::HiLog::Debug(g_LOG_LABEL, "%{public}s", buf);
194 #endif
195 }
196
197 if (g_DebugLogFilleDes != INVALID_FD) {
198 fprintf(stderr, "%s", buf);
199 }
200
201 if (fd != -1) {
202 ret = dprintf(fd, "%s", buf);
203 if (ret < 0) {
204 DfxLogError("WriteLog :: write msg(%s) to fd(%d) failed, ret(%d).", buf, fd, ret);
205 } else {
206 ret = fsync(fd);
207 if (ret < 0) {
208 DfxLogError("WriteLog :: fsync failed, ret(%d).", ret);
209 }
210 }
211 }
212
213 return ret;
214 }
215
DfxLogToSocket(const char * msg)216 void DfxLogToSocket(const char *msg)
217 {
218 if (LOG_LEVEL_CLASS::LOG_LEVEL_DBG < LOG_LEVEL) {
219 return;
220 }
221
222 size_t length = strlen(msg);
223 if (length >= LOG_BUF_LEN) {
224 return;
225 }
226 RequestPrintTHilog(msg, length);
227 }
228
229 #ifndef DFX_LOG_USE_HILOG_BASE
InitDebugLog(int type,int pid,int tid,int uid,bool isLogPersist)230 void InitDebugLog(int type, int pid, int tid, int uid, bool isLogPersist)
231 {
232 DfxLogInfo("InitDebugLog :: type(%d), pid(%d), tid(%d), uid(%d), isLogPersist(%d).",
233 type, pid, tid, uid, isLogPersist);
234 if (g_DebugLogFilleDes != INVALID_FD) {
235 return;
236 }
237 if (!isLogPersist) {
238 return;
239 }
240
241 struct FaultLoggerdRequest faultloggerdRequest;
242 if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) {
243 return;
244 }
245 faultloggerdRequest.type = (int)type;
246 faultloggerdRequest.pid = pid;
247 faultloggerdRequest.tid = tid;
248 faultloggerdRequest.uid = uid;
249
250 g_DebugLogFilleDes = RequestLogFileDescriptor(&faultloggerdRequest);
251 if (g_DebugLogFilleDes <= 0) {
252 DfxLogError("InitDebugLog :: RequestLogFileDescriptor failed.");
253 g_DebugLogFilleDes = INVALID_FD;
254 } else {
255 g_StdErrFilleDes = dup(STDERR_FILENO);
256
257 if (dup2(g_DebugLogFilleDes, STDERR_FILENO) == -1) {
258 DfxLogError("InitDebugLog :: dup2 failed.");
259 close(g_DebugLogFilleDes);
260 g_DebugLogFilleDes = INVALID_FD;
261 g_StdErrFilleDes = INVALID_FD;
262 }
263 }
264 }
265
CloseDebugLog()266 void CloseDebugLog()
267 {
268 if (g_DebugLogFilleDes == INVALID_FD) {
269 return;
270 }
271
272 if (g_StdErrFilleDes != INVALID_FD) {
273 dup2(g_StdErrFilleDes, STDERR_FILENO);
274 }
275 close(g_DebugLogFilleDes);
276 g_DebugLogFilleDes = INVALID_FD;
277 g_StdErrFilleDes = INVALID_FD;
278 }
279 #endif
280