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 BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_LOGGER_H
17 #define BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_LOGGER_H
18 
19 #include <cinttypes>
20 #include <functional>
21 #include <future>
22 #include <string>
23 #include <sstream>
24 
25 #include "hilog/log.h"
26 
27 namespace OHOS {
28 namespace AppExecFwk {
29 inline constexpr uint32_t EH_LOG_DOMAIN = 0xD001201;
30 #define EH_LOG_LIMIT_INTERVALS 10000 //ms
31 } // namespace AppExecFwk
32 } // namespace OHOS
33 
34 #ifndef EH_FUNC_FMT
35 #define EH_FUNC_FMT "in %{public}s:%{public}d, "
36 #endif
37 
38 #ifndef EH_FUNC_INFO
39 #define EH_FUNC_INFO __FUNCTION__, __LINE__
40 #endif
41 
42 #ifndef EH_FILE_NAME
43 #define EH_FILE_NAME   (strrchr((__FILE__), '/') ? strrchr((__FILE__), '/') + 1 : (__FILE__))
44 #endif
45 
46 #ifndef EH_LINE_INFO
47 #define EH_LINE_INFO   EH_FILE_NAME, __LINE__
48 #endif
49 
50 #define DEFINE_EH_HILOG_LABEL(name) \
51     static const constexpr char* EH_LOG_LABEL = (name)
52 
53 #define HILOGD(fmt, ...) do { \
54     if (HiLogIsLoggable(OHOS::AppExecFwk::EH_LOG_DOMAIN, EH_LOG_LABEL, LOG_DEBUG)) { \
55         ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, EH_LOG_DOMAIN, EH_LOG_LABEL, fmt, ##__VA_ARGS__)); \
56     } \
57 } while (0)
58 
59 #define HILOGI(fmt, ...) do { \
60     ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, EH_LOG_DOMAIN, EH_LOG_LABEL, fmt, ##__VA_ARGS__)); \
61 } while (0)
62 
63 #define HILOGW(fmt, ...) do { \
64     ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, EH_LOG_DOMAIN, EH_LOG_LABEL, fmt, ##__VA_ARGS__)); \
65 } while (0)
66 
67 #define HILOGE(fmt, ...) do { \
68     ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, EH_LOG_DOMAIN, EH_LOG_LABEL, fmt, ##__VA_ARGS__)); \
69 } while (0)
70 
71 #define HILOGF(fmt, ...) do { \
72     ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, EH_LOG_DOMAIN, EH_LOG_LABEL, fmt, ##__VA_ARGS__)); \
73 } while (0)
74 
75 #define EH_PRINT_LIMIT(type, level, intervals, canPrint)                               \
76 do {                                                                                    \
77     static auto last = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>();   \
78     static uint32_t supressed = 0;                                                      \
79     auto now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()); \
80     auto duration = now - last;                                                         \
81     if (duration.count() >= (intervals)) {                                              \
82         last = now;                                                                     \
83         uint32_t supressedCnt = supressed;                                              \
84         supressed = 0;                                                                  \
85         if (supressedCnt != 0) {                                                        \
86             ((void)HILOG_IMPL((type), (level), EH_LOG_DOMAIN, EH_LOG_LABEL,    \
87             "[(%{public}s:%{public}d)]log suppressed cnt %{public}u",         \
88             __FUNCTION__, __LINE__, supressedCnt));                       \
89         }                                                                               \
90         (canPrint) = true;                                                              \
91     } else {                                                                            \
92         supressed++;                                                                    \
93         (canPrint) = false;                                                             \
94     }                                                                                   \
95 } while (0)
96 
97 #define EH_LOGF_LIMIT(fmt, ...)                                        \
98 do {                                                                    \
99     bool can = true;                                                    \
100     EH_PRINT_LIMIT(LOG_CORE, LOG_FATAL, EH_LOG_LIMIT_INTERVALS, can); \
101     if (can) {                                                          \
102         HILOGF(fmt, ##__VA_ARGS__);                                   \
103     }                                                                   \
104 } while (0)
105 
106 #define EH_LOGE_LIMIT(fmt, ...)                                        \
107 do {                                                                    \
108     bool can = true;                                                    \
109     EH_PRINT_LIMIT(LOG_CORE, LOG_ERROR, EH_LOG_LIMIT_INTERVALS, can); \
110     if (can) {                                                          \
111         HILOGE(fmt, ##__VA_ARGS__);                                   \
112     }                                                                   \
113 } while (0)
114 
115 #define EH_LOGW_LIMIT(fmt, ...)                                        \
116 do {                                                                    \
117     bool can = true;                                                    \
118     EH_PRINT_LIMIT(LOG_CORE, LOG_WARN, EH_LOG_LIMIT_INTERVALS, can);  \
119     if (can) {                                                          \
120         HILOGW(fmt, ##__VA_ARGS__);                                   \
121     }                                                                   \
122 } while (0)
123 
124 #define EH_LOGI_LIMIT(fmt, ...)                                        \
125 do {                                                                    \
126     bool can = true;                                                    \
127     EH_PRINT_LIMIT(LOG_CORE, LOG_INFO, EH_LOG_LIMIT_INTERVALS, can);  \
128     if (can) {                                                          \
129         HILOGI(fmt, ##__VA_ARGS__);                                   \
130     }                                                                   \
131 } while (0)
132 
133 #define EH_LOGD_LIMIT(fmt, ...)                                        \
134 do {                                                                    \
135     bool can = true;                                                    \
136     EH_PRINT_LIMIT(LOG_CORE, LOG_DEBUG, EH_LOG_LIMIT_INTERVALS, can); \
137     if (can) {                                                          \
138         HILOGD(fmt, ##__VA_ARGS__);                                   \
139     }                                                                   \
140 } while (0)
141 
142 #endif // BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_LOGGER_H
143