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 #include <string_view>
22 #include "hilog/log.h"
23 #include "internal_inc/osal.h"
24 #include "dfx/bbox/fault_logger_fd_manager.h"
25 #else
26 #include "log_base.h"
27 #endif
28 
29 #define FFRT_LOG_ERROR (0)
30 #define FFRT_LOG_WARN (1)
31 #define FFRT_LOG_INFO (2)
32 #define FFRT_LOG_DEBUG (3)
33 #define FFRT_LOG_LEVEL_MAX (FFRT_LOG_DEBUG + 1)
34 
35 unsigned int GetLogId(void);
36 bool IsInWhitelist(void);
37 void InitWhiteListFlag(void);
38 
39 #ifdef OHOS_STANDARD_SYSTEM
40 template<size_t N>
convertFmtToPublic(const char (& str)[N])41 constexpr auto convertFmtToPublic(const char(&str)[N])
42 {
43     constexpr std::string_view fmtpub = "{public}";
44     std::array<char, (N / 2) * fmtpub.size() + N> res{};
45     for (size_t i = 0, j = 0; i < N; ++i) {
46         res[j++] = str[i];
47         if (str[i] != '%') {
48             continue;
49         }
50 
51         if (str[i + 1] != '%' && str[i + 1] != '{') {
52             for (size_t k = 0; k < fmtpub.size(); ++k) {
53                 res[j++] = fmtpub[k];
54             }
55         } else {
56             res[j++] = str[i + 1];
57             i += 1;
58         }
59     }
60 
61     return res;
62 }
63 
64 #ifdef HILOG_FMTID
65 #define HILOG_IMPL_STD_ARRAY(type, level, fmt, ...) \
66     do { \
67         constexpr HILOG_FMT_IN_SECTION static auto hilogFmt = fmt; \
68         FmtId fmtid{ HILOG_UUID, HILOG_FMT_OFFSET(hilogFmt.data()) }; \
69         HiLogPrintDict(type, level, 0xD001719, "ffrt", &fmtid, hilogFmt.data(), ##__VA_ARGS__); \
70     } while (0)
71 #else
72 #define HILOG_IMPL_STD_ARRAY(type, level, fmt, ...) \
73     do { \
74         HiLogPrint(type, level, 0xD001719, "ffrt", fmt.data(), ##__VA_ARGS__); \
75     } while (0)
76 #endif
77 
78 #if (FFRT_LOG_LEVEL >= FFRT_LOG_DEBUG)
79 #define FFRT_LOGD(format, ...) \
80     do { \
81         if (unlikely(IsInWhitelist())) { \
82             constexpr auto fmtPub = convertFmtToPublic("%u:%s:%d " format); \
83             HILOG_IMPL_STD_ARRAY(LOG_CORE, LOG_DEBUG, fmtPub, GetLogId(), __func__, __LINE__, ##__VA_ARGS__); \
84         } \
85     } while (0)
86 #else
87 #define FFRT_LOGD(format, ...)
88 #endif
89 
90 #if (FFRT_LOG_LEVEL >= FFRT_LOG_INFO)
91 #define FFRT_LOGI(format, ...) \
92     do { \
93         constexpr auto fmtPub = convertFmtToPublic("%u:%s:%d " format); \
94         HILOG_IMPL_STD_ARRAY(LOG_CORE, LOG_INFO, fmtPub, GetLogId(), __func__, __LINE__, ##__VA_ARGS__); \
95     } while (0)
96 #else
97 #define FFRT_LOGI(format, ...)
98 #endif
99 
100 #if (FFRT_LOG_LEVEL >= FFRT_LOG_WARN)
101 #define FFRT_LOGW(format, ...) \
102     do { \
103         constexpr auto fmtPub = convertFmtToPublic("%u:%s:%d " format); \
104         HILOG_IMPL_STD_ARRAY(LOG_CORE, LOG_WARN, fmtPub, GetLogId(), __func__, __LINE__, ##__VA_ARGS__); \
105     } while (0)
106 #else
107 #define FFRT_LOGW(format, ...)
108 #endif
109 
110 #define FFRT_LOGE(format, ...) \
111     do { \
112         constexpr auto fmtPub = convertFmtToPublic("%u:%s:%d " format); \
113         HILOG_IMPL_STD_ARRAY(LOG_CORE, LOG_ERROR, fmtPub, GetLogId(), __func__, __LINE__, ##__VA_ARGS__); \
114     } while (0)
115 #else
116 #if (FFRT_LOG_LEVEL >= FFRT_LOG_DEBUG)
117 #define FFRT_LOGD(format, ...) FFRT_LOG(FFRT_LOG_DEBUG, format, ##__VA_ARGS__)
118 #else
119 #define FFRT_LOGD(format, ...)
120 #endif
121 
122 #if (FFRT_LOG_LEVEL >= FFRT_LOG_INFO)
123 #define FFRT_LOGI(format, ...) FFRT_LOG(FFRT_LOG_INFO, format, ##__VA_ARGS__)
124 #else
125 #define FFRT_LOGI(format, ...)
126 #endif
127 
128 #if (FFRT_LOG_LEVEL >= FFRT_LOG_WARN)
129 #define FFRT_LOGW(format, ...) FFRT_LOG(FFRT_LOG_WARN, format, ##__VA_ARGS__)
130 #else
131 #define FFRT_LOGW(format, ...)
132 #endif
133 
134 #define FFRT_LOGE(format, ...) FFRT_LOG(FFRT_LOG_ERROR, format, ##__VA_ARGS__)
135 #endif
136 
137 
138 #ifdef OHOS_STANDARD_SYSTEM
139 #define FFRT_BBOX_LOG(format, ...) \
140     do { \
141         FFRT_LOGE(format, ##__VA_ARGS__); \
142         FaultLoggerFdManager::Instance().WriteFaultLogger(format, ##__VA_ARGS__); \
143     } while (0)
144 #else
145 #define FFRT_BBOX_LOG(format, ...) FFRT_LOGE(format, ##__VA_ARGS__)
146 #endif
147 
148 #define FFRT_COND_DO_ERR(cond, expr, format, ...) \
149     if (cond) {                                   \
150         FFRT_LOGE(format, ##__VA_ARGS__);         \
151         {                                         \
152             expr;                                 \
153         }                                         \
154     }
155 
156 // Do not use this Marco directly
157 #define COND_RETURN_(COND, ERRCODE, ...) \
158     if ((COND)) { \
159         FFRT_LOGE(__VA_ARGS__); \
160         return ERRCODE; \
161     }
162 
163 #define FFRT_COND_RETURN_ERROR(COND, ERRCODE, ...) \
164     COND_RETURN_((COND), ERRCODE, ##__VA_ARGS__)
165 
166 #define FFRT_COND_RETURN_VOID(COND, ...) \
167     if ((COND)) { \
168         FFRT_LOGE(__VA_ARGS__); \
169         return; \
170     }
171 
172 // Do not use this Marco directly
173 #define COND_GOTO_WITH_ERRCODE_(COND, LABEL, ERROR, ERRCODE, ...) \
174     if ((COND)) { \
175         FFRT_LOGE(__VA_ARGS__); \
176         ERROR = (ERRCODE); \
177         goto LABEL; \
178     }
179 
180 #define FFRT_COND_GOTO_ERROR(COND, LABEL, ERROR, ERRCODE, ...) \
181     COND_GOTO_WITH_ERRCODE_((COND), LABEL, ERROR, ERRCODE, ##__VA_ARGS__)
182 
183 #define FFRT_UNUSED(expr) \
184     do { \
185         (void)(expr); \
186     } while (0)
187 
188 #ifdef FFRT_ENG_DEBUG
189 #define FFRT_UNLIKELY_COND_DO_ABORT(cond, fmt, ...) \
190     do { \
191         if (unlikely(cond)) { \
192             FFRT_LOGE(fmt, ##__VA_ARGS__); \
193             abort(); \
194         } \
195     } while (0)
196 
197 #else
198 #define FFRT_UNLIKELY_COND_DO_ABORT(cond, fmt, ...) \
199     do { \
200         if (unlikely(cond)) { \
201             FFRT_LOGE(fmt, ##__VA_ARGS__); \
202         } \
203     } while (0)
204 #endif // FFRT_ENG_DEBUG
205 #endif // __FFRT_LOG_API_H__
206