1/*
2 * Copyright (c) 2021-2024 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 FOUNDATION_ACE_FRAMEWORKS_BASE_LOG_LOG_WRAPPER_H
17#define FOUNDATION_ACE_FRAMEWORKS_BASE_LOG_LOG_WRAPPER_H
18
19#include <cstdarg>
20#include <cstdint>
21#include <cstring>
22#include <string>
23#include <unordered_map>
24
25#include "base/utils/macros.h"
26#include "base/utils/system_properties.h"
27
28#ifdef ACE_INSTANCE_LOG
29#define ACE_FMT_PREFIX "[%{public}s(%{public}d)-(%{public}s)] "
30#define ACE_LOG_ID_WITH_REASON , OHOS::Ace::LogWrapper::GetIdWithReason().c_str()
31#else
32#define ACE_FMT_PREFIX "[%{private}s(%{private}d)] "
33#define ACE_LOG_ID_WITH_REASON
34#endif
35
36#if defined(USE_HILOG)
37#include "hilog/log.h"
38constexpr uint32_t ACE_DOMAIN = 0xD003900;
39constexpr uint32_t APP_DOMAIN = 0xC0D0;
40#ifdef IS_RELEASE_VERSION
41#define PRINT_LOG(level, tag, fmt, ...) \
42    HILOG_IMPL(LOG_CORE, LOG_##level, (tag + ACE_DOMAIN), (OHOS::Ace::g_DOMAIN_CONTENTS_MAP.at(tag)),         \
43            "[(%{public}s)] " fmt, OHOS::Ace::LogWrapper::GetIdWithReason().c_str(), ##__VA_ARGS__)
44#else
45#define PRINT_LOG(level, tag, fmt, ...) \
46    HILOG_IMPL(LOG_CORE, LOG_##level, (tag + ACE_DOMAIN), (OHOS::Ace::g_DOMAIN_CONTENTS_MAP.at(tag)),         \
47            ACE_FMT_PREFIX fmt, OHOS::Ace::LogWrapper::GetBriefFileName(__FILE__),                            \
48            __LINE__ ACE_LOG_ID_WITH_REASON, ##__VA_ARGS__)
49#endif
50#define PRINT_APP_LOG(level, fmt, ...) HILOG_IMPL(LOG_APP, LOG_##level, APP_DOMAIN, "JSAPP", fmt, ##__VA_ARGS__)
51#else
52#define PRINT_LOG(level, tag, fmt, ...)                                                                       \
53    do {                                                                                                      \
54        if (OHOS::Ace::LogWrapper::JudgeLevel(OHOS::Ace::LogLevel::level)) {                                  \
55            OHOS::Ace::LogWrapper::PrintLog(OHOS::Ace::LogDomain::FRAMEWORK, OHOS::Ace::LogLevel::level, tag, \
56                ACE_FMT_PREFIX fmt, OHOS::Ace::LogWrapper::GetBriefFileName(__FILE__),                        \
57                __LINE__ ACE_LOG_ID_WITH_REASON, ##__VA_ARGS__);                                          \
58        }                                                                                                     \
59    } while (0)
60
61#define PRINT_APP_LOG(level, fmt, ...) \
62    OHOS::Ace::LogWrapper::PrintLog(   \
63        OHOS::Ace::LogDomain::JS_APP, OHOS::Ace::LogLevel::level, OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN,   \
64        fmt, ##__VA_ARGS__)
65#endif
66
67#define LOGD(fmt, ...) TAG_LOGD(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, fmt, ##__VA_ARGS__)
68#define LOGI(fmt, ...) TAG_LOGI(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, fmt, ##__VA_ARGS__)
69#define LOGW(fmt, ...) TAG_LOGW(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, fmt, ##__VA_ARGS__)
70#define LOGE(fmt, ...) TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, fmt, ##__VA_ARGS__)
71#define LOGF(fmt, ...) TAG_LOGF(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, fmt, ##__VA_ARGS__)
72
73#define TAG_LOGD(tag, fmt, ...) PRINT_LOG(DEBUG, tag, fmt, ##__VA_ARGS__)
74#define TAG_LOGI(tag, fmt, ...) PRINT_LOG(INFO, tag, fmt, ##__VA_ARGS__)
75#define TAG_LOGW(tag, fmt, ...) PRINT_LOG(WARN, tag, fmt, ##__VA_ARGS__)
76#define TAG_LOGE(tag, fmt, ...) PRINT_LOG(ERROR, tag, fmt, ##__VA_ARGS__)
77#define TAG_LOGF(tag, fmt, ...) PRINT_LOG(FATAL, tag, fmt, ##__VA_ARGS__)
78
79#define LOG_FUNCTION() LOGD("function track: %{public}s", __FUNCTION__)
80
81#define APP_LOGD(fmt, ...) PRINT_APP_LOG(DEBUG, fmt, ##__VA_ARGS__)
82#define APP_LOGI(fmt, ...) PRINT_APP_LOG(INFO, fmt, ##__VA_ARGS__)
83#define APP_LOGW(fmt, ...) PRINT_APP_LOG(WARN, fmt, ##__VA_ARGS__)
84#define APP_LOGE(fmt, ...) PRINT_APP_LOG(ERROR, fmt, ##__VA_ARGS__)
85#define APP_LOGF(fmt, ...) PRINT_APP_LOG(FATAL, fmt, ##__VA_ARGS__)
86
87#define JSON_STRING_PUT_INT(jsonValue, var) (jsonValue)->Put(#var, static_cast<int64_t>(var))
88#define JSON_STRING_PUT_BOOL(jsonValue, var) (jsonValue)->Put(#var, (var))
89#define JSON_STRING_PUT_STRING(jsonValue, var) (jsonValue)->Put(#var, (var).c_str())
90#define JSON_STRING_PUT_STRINGABLE(jsonValue, var) (jsonValue)->Put(#var, (var).ToString().c_str())
91
92#define JSON_STRING_PUT_OPTIONAL_INT(jsonValue, var)          \
93    do {                                                      \
94        if (var) {                                            \
95            (jsonValue)->Put(#var, static_cast<int64_t>(*(var))); \
96        }                                                     \
97    } while (0)                                               \
98
99#define JSON_STRING_PUT_OPTIONAL_STRING(jsonValue, var) \
100    do {                                                \
101        if (var) {                                      \
102            (jsonValue)->Put(#var, (var)->c_str());         \
103        }                                               \
104    } while (0)                                         \
105
106
107#define JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, var) \
108    do {                                                    \
109        if (var) {                                          \
110            (jsonValue)->Put(#var, (var)->ToString().c_str());  \
111        }                                                   \
112    } while (0)                                             \
113
114
115namespace OHOS::Ace {
116enum AceLogTag : uint8_t {
117    ACE_DEFAULT_DOMAIN = 0,        // C03900
118    ACE_ALPHABET_INDEXER = 1,      // C03901
119    ACE_COUNTER = 2,               // C03902
120    ACE_SUB_WINDOW = 3,            // C03903
121    ACE_FORM = 4,                  // C03904
122    ACE_DRAG = 5,                  // C03905
123    ACE_VIDEO = 6,                 // C03906
124    ACE_COMPONENT_SNAPSHOT = 7,    // C03907
125    ACE_CANVAS = 8,                // C03908
126    ACE_REFRESH = 9,               // C03909
127    ACE_SCROLL = 10,               // C0390A
128    ACE_SCROLLABLE = 11,           // C0390B
129    ACE_FONT = 12,                 // C0390C
130    ACE_OVERLAY = 13,              // C0390D
131    ACE_DIALOG_TIMEPICKER = 14,    // C0390E
132    ACE_DIALOG = 15,               // C0390F
133    ACE_PANEL = 16,                // C03910
134    ACE_MENU = 17,                 // C03911
135    ACE_TEXTINPUT = 18,            // C03912
136    ACE_TEXT = 19,                 // C03913
137    ACE_TEXT_FIELD = 20,           // C03914
138    ACE_SWIPER = 21,               // C03915
139    ACE_TABS = 22,                 // C03916
140    ACE_BLANK = 23,                // C03917
141    ACE_GRIDROW = 24,              // C03918
142    ACE_INPUTTRACKING = 25,        // C03919
143    ACE_RICH_TEXT = 26,            // C0391A
144    ACE_WEB = 27,                  // C0391B
145    ACE_FOCUS = 28,                // C0391C
146    ACE_MOUSE = 29,                // C0391D
147    ACE_GESTURE = 30,              // C0391E
148    ACE_IMAGE = 31,                // C0391F
149    ACE_RATING = 32,               // C03920
150    ACE_LIST = 33,                 // C03921
151    ACE_NAVIGATION = 34,           // C03922
152    ACE_WATERFLOW = 35,            // C03923
153    ACE_ACCESSIBILITY = 36,        // C03924
154    ACE_ROUTER = 37,               // C03925
155    ACE_THEME = 38,                // C03926
156    ACE_BORDER_IMAGE = 39,         // C03927
157    ACE_GRID = 40,                 // C03928
158    ACE_PLUGIN_COMPONENT = 41,     // C03929
159    ACE_UIEXTENSIONCOMPONENT = 42, // C0392A
160    ACE_IF = 43,                   // C0392B
161    ACE_FOREACH = 44,              // C0392C
162    ACE_LAZY_FOREACH = 45,         // C0392D
163    ACE_GAUGE = 46,                // C0392E
164    ACE_HYPERLINK = 47,            // C0392F
165    ACE_ANIMATION = 48,            // C03930
166    ACE_XCOMPONENT = 49,           // C03931
167    ACE_AUTO_FILL = 50,            // C03932
168    ACE_KEYBOARD = 51,             // C03933
169    ACE_UIEVENT = 52,              // C03934
170    ACE_UI_SERVICE = 53,           // C03935 ace_engine/adapter/ohos/services/uiservice/src/ui_service_hilog.h
171    ACE_DISPLAY_SYNC = 54,         // C03936
172    ACE_RESOURCE = 55,             // C03937
173    ACE_SIDEBAR = 56,              // C03938
174    ACE_GEOMETRY_TRANSITION = 57,  // C03939
175    ACE_DOWNLOAD_MANAGER = 58,     // C0393A
176    ACE_WINDOW_SCENE = 59,         // C0393B
177    ACE_NODE_CONTAINER = 60,       // C0393C
178    ACE_NATIVE_NODE = 61,          // C0393D
179    ACE_ISOLATED_COMPONENT = 62,   // C0393E
180    ACE_MARQUEE = 63,              // C0393F
181    ACE_OBSERVER = 64,             // C03940
182    ACE_EMBEDDED_COMPONENT = 65,   // C03941
183    ACE_TEXT_CLOCK = 66,           // C03942
184    ACE_FOLDER_STACK = 67,         // C03943
185    ACE_SELECT_COMPONENT = 68,     // C03944
186    ACE_STATE_STYLE = 69,          // C03945
187    ACE_SEARCH = 70,               // C03946
188    ACE_STATE_MGMT = 71,           // C03947
189    ACE_REPEAT = 72,               // C03948
190    ACE_SHEET = 73,                // C03949
191    ACE_CANVAS_COMPONENT = 74,     // C0394A
192    ACE_SCROLL_BAR = 75,           // C0394B
193    ACE_MOVING_PHOTO = 76,         // C0394C
194    ACE_ARK_COMPONENT = 77,        // C0394D
195    ACE_WINDOW = 78,               // C0394E
196    ACE_SECURITYUIEXTENSION = 79,  // C0394F
197    ACE_WINDOW_PIPELINE = 80,      // C03950
198    ACE_INPUTKEYFLOW = 81,         // C03951
199    ACE_APPBAR = 82,               // C03952
200    ACE_SELECT_OVERLAY = 83,       // C03953
201    ACE_CLIPBOARD = 84,            // C03954
202    ACE_VISUAL_EFFECT = 85,        // C03955
203    ACE_SECURITY_COMPONENT = 86,   // C03956
204    ACE_MEDIA_QUERY = 87,          // C03957
205    ACE_LAYOUT_INSPECTOR = 88,     // C03958
206    ACE_LAYOUT = 89,               // C03959
207    ACE_STYLUS = 90,               // C0395A
208    ACE_INDICATOR = 91,            // C0395B
209
210    FORM_RENDER = 255, // C039FF FormRenderer, last domain, do not add
211};
212
213ACE_FORCE_EXPORT extern const std::unordered_map<AceLogTag, const char*> g_DOMAIN_CONTENTS_MAP;
214
215enum class LogDomain : uint32_t {
216    FRAMEWORK = 0,
217    JS_APP,
218};
219
220enum class LogLevel : uint32_t {
221    DEBUG = 0,
222    INFO,
223    WARN,
224    ERROR,
225    FATAL,
226};
227
228class ACE_FORCE_EXPORT LogWrapper final {
229public:
230    static bool JudgeLevel(LogLevel level)
231    {
232        if (level == LogLevel::DEBUG) {
233            return SystemProperties::GetDebugEnabled();
234        }
235        return level_ <= level;
236    }
237
238    static void SetLogLevel(LogLevel level)
239    {
240        level_ = level;
241    }
242
243    static LogLevel GetLogLevel()
244    {
245        return level_;
246    }
247
248    static const char* GetBriefFileName(const char* name)
249    {
250        static const char separator = GetSeparatorCharacter();
251        const char* p = strrchr(name, separator);
252        return p != nullptr ? p + 1 : name;
253    }
254
255    static void StripFormatString(const std::string& prefix, std::string& str)
256    {
257        for (auto pos = str.find(prefix, 0); pos != std::string::npos; pos = str.find(prefix, pos)) {
258            str.erase(pos, prefix.size());
259        }
260    }
261
262    static void ReplaceFormatString(const std::string& prefix, const std::string& replace, std::string& str)
263    {
264        for (auto pos = str.find(prefix, 0); pos != std::string::npos; pos = str.find(prefix, pos)) {
265            str.replace(pos, prefix.size(), replace);
266        }
267    }
268
269    static void PrintLog(LogDomain domain, LogLevel level, AceLogTag tag, const char* fmt, ...)
270        __attribute__((__format__(os_log, 4, 5)))
271    {
272        va_list args;
273        va_start(args, fmt);
274        PrintLog(domain, level, tag, fmt, args);
275        va_end(args);
276    }
277
278    // MUST implement these interface on each platform.
279    static char GetSeparatorCharacter();
280    static void PrintLog(LogDomain domain, LogLevel level, AceLogTag tag, const char* fmt, va_list args);
281#ifdef ACE_INSTANCE_LOG
282    static int32_t GetId();
283    static const std::string GetIdWithReason();
284#endif
285
286private:
287    LogWrapper() = delete;
288    ~LogWrapper() = delete;
289
290    static LogLevel level_;
291};
292
293bool LogBacktrace(size_t maxFrameNums = 256);
294} // namespace OHOS::Ace
295
296#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_LOG_LOG_WRAPPER_H
297