1 /*
2 * Copyright (c) 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 #ifndef __FFRT_LOG_API_H__
17 #define __FFRT_LOG_API_H__
18
19 #ifdef OHOS_STANDARD_SYSTEM
20 #include <array>
21 #ifdef FFRT_ENG_DEBUG
22 #include <info/fatal_message.h>
23 #endif
24 #include <string_view>
25 #include "hilog/log.h"
26 #include "internal_inc/osal.h"
27 #include "dfx/bbox/fault_logger_fd_manager.h"
28 #else
29 #include "log_base.h"
30 #endif
31 #include <stdbool.h>
32
33 #define FFRT_LOG_ERROR (0)
34 #define FFRT_LOG_WARN (1)
35 #define FFRT_LOG_INFO (2)
36 #define FFRT_LOG_DEBUG (3)
37 #define FFRT_LOG_LEVEL_MAX (FFRT_LOG_DEBUG + 1)
38
39 unsigned int GetLogId(void);
40 bool IsInWhitelist(void);
41 void InitWhiteListFlag(void);
42 #ifdef FFRT_SEND_EVENT
43 void ReportSysEvent(const char* format, ...);
44 #endif
45
46 #ifdef OHOS_STANDARD_SYSTEM
47 template<size_t N>
convertFmtToPublic(const char (& str)[N])48 constexpr auto convertFmtToPublic(const char(&str)[N])
49 {
50 constexpr std::string_view fmtpub = "{public}";
51 std::array<char, (N / 2) * fmtpub.size() + N> res{};
52 for (size_t i = 0, j = 0; i < N; ++i) {
53 res[j++] = str[i];
54 if (str[i] != '%') {
55 continue;
56 }
57
58 if (str[i + 1] != '%' && str[i + 1] != '{') {
59 for (size_t k = 0; k < fmtpub.size(); ++k) {
60 res[j++] = fmtpub[k];
61 }
62 } else {
63 res[j++] = str[i + 1];
64 i += 1;
65 }
66 }
67
68 return res;
69 }
70
71 #ifdef HILOG_FMTID
72 #define HILOG_IMPL_STD_ARRAY(type, level, fmt, ...) \
73 do { \
74 constexpr HILOG_FMT_IN_SECTION static auto hilogFmt = fmt; \
75 FmtId fmtid{ HILOG_UUID, HILOG_FMT_OFFSET(hilogFmt.data()) }; \
76 HiLogPrintDict(type, level, 0xD001719, "ffrt", &fmtid, hilogFmt.data(), ##__VA_ARGS__); \
77 } while (0)
78 #else
79 #define HILOG_IMPL_STD_ARRAY(type, level, fmt, ...) \
80 do { \
81 HiLogPrint(type, level, 0xD001719, "ffrt", fmt.data(), ##__VA_ARGS__); \
82 } while (0)
83 #endif
84
85 #if (FFRT_LOG_LEVEL >= FFRT_LOG_DEBUG)
86 #define FFRT_LOGD(format, ...) \
87 do { \
88 if (unlikely(IsInWhitelist())) { \
89 constexpr auto fmtPub = convertFmtToPublic("%u:%s:%d " format); \
90 HILOG_IMPL_STD_ARRAY(LOG_CORE, LOG_DEBUG, fmtPub, GetLogId(), __func__, __LINE__, ##__VA_ARGS__); \
91 } \
92 } while (0)
93 #else
94 #define FFRT_LOGD(format, ...)
95 #endif
96
97 #if (FFRT_LOG_LEVEL >= FFRT_LOG_INFO)
98 #define FFRT_LOGI(format, ...) \
99 do { \
100 constexpr auto fmtPub = convertFmtToPublic("%u:%s:%d " format); \
101 HILOG_IMPL_STD_ARRAY(LOG_CORE, LOG_INFO, fmtPub, GetLogId(), __func__, __LINE__, ##__VA_ARGS__); \
102 } while (0)
103 #else
104 #define FFRT_LOGI(format, ...)
105 #endif
106
107 #if (FFRT_LOG_LEVEL >= FFRT_LOG_WARN)
108 #define FFRT_LOGW(format, ...) \
109 do { \
110 constexpr auto fmtPub = convertFmtToPublic("%u:%s:%d " format); \
111 HILOG_IMPL_STD_ARRAY(LOG_CORE, LOG_WARN, fmtPub, GetLogId(), __func__, __LINE__, ##__VA_ARGS__); \
112 } while (0)
113 #else
114 #define FFRT_LOGW(format, ...)
115 #endif
116
117 #define FFRT_LOGE(format, ...) \
118 do { \
119 constexpr auto fmtPub = convertFmtToPublic("%u:%s:%d " format); \
120 HILOG_IMPL_STD_ARRAY(LOG_CORE, LOG_ERROR, fmtPub, GetLogId(), __func__, __LINE__, ##__VA_ARGS__); \
121 } while (0)
122 #else
123 #if (FFRT_LOG_LEVEL >= FFRT_LOG_DEBUG)
124 #define FFRT_LOGD(format, ...) FFRT_LOG(FFRT_LOG_DEBUG, format, ##__VA_ARGS__)
125 #else
126 #define FFRT_LOGD(format, ...)
127 #endif
128
129 #if (FFRT_LOG_LEVEL >= FFRT_LOG_INFO)
130 #define FFRT_LOGI(format, ...) FFRT_LOG(FFRT_LOG_INFO, format, ##__VA_ARGS__)
131 #else
132 #define FFRT_LOGI(format, ...)
133 #endif
134
135 #if (FFRT_LOG_LEVEL >= FFRT_LOG_WARN)
136 #define FFRT_LOGW(format, ...) FFRT_LOG(FFRT_LOG_WARN, format, ##__VA_ARGS__)
137 #else
138 #define FFRT_LOGW(format, ...)
139 #endif
140
141 #define FFRT_LOGE(format, ...) FFRT_LOG(FFRT_LOG_ERROR, format, ##__VA_ARGS__)
142 #endif
143
144
145 #ifdef OHOS_STANDARD_SYSTEM
146 #define FFRT_BBOX_LOG(format, ...) \
147 do { \
148 FFRT_LOGE(format, ##__VA_ARGS__); \
149 FaultLoggerFdManager::WriteFaultLogger(format, ##__VA_ARGS__); \
150 } while (0)
151 #else
152 #define FFRT_BBOX_LOG(format, ...) FFRT_LOGE(format, ##__VA_ARGS__)
153 #endif
154
155 #ifdef FFRT_SEND_EVENT
156 #define FFRT_SYSEVENT_LOGE(format, ...) \
157 do { \
158 FFRT_LOGE(format, ##__VA_ARGS__); \
159 ReportSysEvent(format, ##__VA_ARGS__); \
160 } while (0)
161 #define FFRT_SYSEVENT_LOGW(format, ...) \
162 do { \
163 FFRT_LOGW(format, ##__VA_ARGS__); \
164 ReportSysEvent(format, ##__VA_ARGS__); \
165 } while (0)
166 #define FFRT_SYSEVENT_LOGI(format, ...) \
167 do { \
168 FFRT_LOGI(format, ##__VA_ARGS__); \
169 ReportSysEvent(format, ##__VA_ARGS__); \
170 } while (0)
171 #define FFRT_SYSEVENT_LOGD(format, ...) \
172 do { \
173 FFRT_LOGD(format, ##__VA_ARGS__); \
174 ReportSysEvent(format, ##__VA_ARGS__); \
175 } while (0)
176 #else // FFRT_SEND_EVENT
177 #define FFRT_SYSEVENT_LOGE(format, ...) FFRT_LOGE(format, ##__VA_ARGS__)
178 #define FFRT_SYSEVENT_LOGW(format, ...) FFRT_LOGW(format, ##__VA_ARGS__)
179 #define FFRT_SYSEVENT_LOGI(format, ...) FFRT_LOGI(format, ##__VA_ARGS__)
180 #define FFRT_SYSEVENT_LOGD(format, ...) FFRT_LOGD(format, ##__VA_ARGS__)
181 #endif // FFRT_SEND_EVENT
182
183 #define FFRT_COND_DO_ERR(cond, expr, format, ...) \
184 if (cond) { \
185 FFRT_LOGE(format, ##__VA_ARGS__); \
186 { \
187 expr; \
188 } \
189 }
190
191 // Do not use this Marco directly
192 #define COND_RETURN_(COND, ERRCODE, ...) \
193 if ((COND)) { \
194 FFRT_LOGE(__VA_ARGS__); \
195 return ERRCODE; \
196 }
197
198 #define FFRT_COND_RETURN_ERROR(COND, ERRCODE, ...) \
199 COND_RETURN_((COND), ERRCODE, ##__VA_ARGS__)
200
201 #define FFRT_COND_RETURN_VOID(COND, ...) \
202 if ((COND)) { \
203 FFRT_LOGE(__VA_ARGS__); \
204 return; \
205 }
206
207 // Do not use this Marco directly
208 #define COND_GOTO_WITH_ERRCODE_(COND, LABEL, ERROR, ERRCODE, ...) \
209 if ((COND)) { \
210 FFRT_LOGE(__VA_ARGS__); \
211 ERROR = (ERRCODE); \
212 goto LABEL; \
213 }
214
215 #define FFRT_COND_GOTO_ERROR(COND, LABEL, ERROR, ERRCODE, ...) \
216 COND_GOTO_WITH_ERRCODE_((COND), LABEL, ERROR, ERRCODE, ##__VA_ARGS__)
217
218 #define FFRT_UNUSED(expr) \
219 do { \
220 (void)(expr); \
221 } while (0)
222
223 #if defined(FFRT_ENG_DEBUG) && defined(OHOS_STANDARD_SYSTEM)
224 #define FFRT_UNLIKELY_COND_DO_ABORT(cond, fmt, ...) \
225 do { \
226 if (unlikely(cond)) { \
227 char fatal_msg[256]; \
228 snprintf_s(fatal_msg, sizeof(fatal_msg), sizeof(fatal_msg) - 1, fmt, ##__VA_ARGS__); \
229 FFRT_LOGE(fmt, ##__VA_ARGS__); \
230 set_fatal_message(fatal_msg); \
231 abort(); \
232 } \
233 } while (0)
234
235 #else
236 #define FFRT_UNLIKELY_COND_DO_ABORT(cond, fmt, ...) \
237 do { \
238 if (unlikely(cond)) { \
239 FFRT_LOGE(fmt, ##__VA_ARGS__); \
240 } \
241 } while (0)
242 #endif // FFRT_ENG_DEBUG
243
244 #if defined(FFRT_ENG_DEBUG) && defined(OHOS_STANDARD_SYSTEM)
245 #define FFRT_COND_TERMINATE(cond, fmt, ...) \
246 do { \
247 if (cond) { \
248 char fatal_msg[256]; \
249 snprintf_s(fatal_msg, sizeof(fatal_msg), sizeof(fatal_msg) - 1, fmt, ##__VA_ARGS__); \
250 FFRT_SYSEVENT_LOGE(fmt, ##__VA_ARGS__); \
251 set_fatal_message(fatal_msg); \
252 std::terminate(); \
253 } \
254 } while (0)
255 #else
256 #define FFRT_COND_TERMINATE(cond, fmt, ...) \
257 do { \
258 if (cond) { \
259 FFRT_SYSEVENT_LOGE(fmt, ##__VA_ARGS__); \
260 std::terminate(); \
261 } \
262 } while (0)
263 #endif // FFRT_ENG_DEBUG
264 #endif // __FFRT_LOG_API_H__
265