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 
16 #ifndef BASE_NOTIFICATION_ANS_STANDARD_INNERKITS_BASE_INCLUDE_ANS_LOG_HELPER_H
17 #define BASE_NOTIFICATION_ANS_STANDARD_INNERKITS_BASE_INCLUDE_ANS_LOG_HELPER_H
18 
19 #include <stdint.h>         // for uint8_t
20 #include <string>           // for basic_string
21 
22 #include "hilog/log.h"
23 #include <chrono>
24 
25 namespace OHOS {
26 namespace Notification {
27 #ifndef ANS_LOG_DOMAIN
28 #define ANS_LOG_DOMAIN 0xD001203
29 #endif
30 
31 #ifndef ANS_LOG_TAG
32 #define ANS_LOG_TAG "Ans"
33 #endif
34 
35 #ifndef ANS_REMINDER_LOG_TAG
36 #define ANS_REMINDER_LOG_TAG "ANS_REMINDER"
37 #endif
38 
39 #define ANS_LOG_LIMIT_INTERVALS 10000 //ms
40 
41 enum class AnsLogLevel : uint8_t { DEBUG = 0, INFO, WARN, ERROR, FATAL };
42 
43 static constexpr OHOS::HiviewDFX::HiLogLabel ANS_LABEL = {LOG_CORE, ANS_LOG_DOMAIN, ANS_LOG_TAG};
44 static constexpr OHOS::HiviewDFX::HiLogLabel ANS_REMINDER_LABEL = {LOG_CORE, ANS_LOG_DOMAIN, ANS_REMINDER_LOG_TAG};
45 
46 class AnsLogWrapper {
47 public:
48     AnsLogWrapper() = delete;
49     ~AnsLogWrapper() = delete;
50 
51     /**
52      * @brief Judge the level of the log.
53      *
54      * @param level Indicates the level of the log.
55      * @return Returns ture on passed, otherwise false.
56      */
57     static bool JudgeLevel(const AnsLogLevel &level);
58 
59     /**
60      * @brief Set the level of the log.
61      *
62      * @param level Indicates the level of the log.
63      */
SetLogLevel(const AnsLogLevel & level)64     static void SetLogLevel(const AnsLogLevel &level)
65     {
66         level_ = level;
67     }
68 
69     /**
70      * @brief Get the level of the log.
71      *
72      * @return Indicates the level of the log.
73      */
GetLogLevel()74     static const AnsLogLevel &GetLogLevel()
75     {
76         return level_;
77     }
78 
79     /**
80      * @brief Get the brief name of the file.
81      *
82      * @param str Indicates the full name of the file.
83      * @return Indicates the file name.
84      */
85     static std::string GetBriefFileName(const char *str);
86 
87 private:
88     static AnsLogLevel level_;
89 };
90 
91 #define CUR_FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
92 
93 #define ANS_LOGF(fmt, ...)            \
94     ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, ANS_LOG_DOMAIN, ANS_LOG_TAG, \
95     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
96 #define ANS_LOGE(fmt, ...)            \
97     ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, ANS_LOG_DOMAIN, ANS_LOG_TAG, \
98     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
99 #define ANS_LOGW(fmt, ...)            \
100     ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, ANS_LOG_DOMAIN, ANS_LOG_TAG, \
101     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
102 #define ANS_LOGI(fmt, ...)            \
103     ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, ANS_LOG_DOMAIN, ANS_LOG_TAG, \
104     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
105 #define ANS_LOGD(fmt, ...)            \
106     ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, ANS_LOG_DOMAIN, ANS_LOG_TAG, \
107     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
108 
109 #define ANSR_LOGF(fmt, ...)            \
110     ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, ANS_LOG_DOMAIN, ANS_REMINDER_LOG_TAG, \
111     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
112 #define ANSR_LOGE(fmt, ...)            \
113     ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, ANS_LOG_DOMAIN, ANS_REMINDER_LOG_TAG, \
114     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
115 #define ANSR_LOGW(fmt, ...)            \
116     ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, ANS_LOG_DOMAIN, ANS_REMINDER_LOG_TAG, \
117     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
118 #define ANSR_LOGI(fmt, ...)            \
119     ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, ANS_LOG_DOMAIN, ANS_REMINDER_LOG_TAG, \
120     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
121 #define ANSR_LOGD(fmt, ...)            \
122     ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, ANS_LOG_DOMAIN, ANS_REMINDER_LOG_TAG, \
123     "[%{public}s(%{public}s:%{public}d)]" fmt, CUR_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__))
124 
125 #define ANS_PRINT_LIMIT(type, level, intervals, canPrint)                               \
126 do {                                                                                    \
127     static auto last = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>();   \
128     static uint32_t supressed = 0;                                                      \
129     auto now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()); \
130     auto duration = now - last;                                                         \
131     if (duration.count() >= (intervals)) {                                              \
132         last = now;                                                                     \
133         uint32_t supressedCnt = supressed;                                              \
134         supressed = 0;                                                                  \
135         if (supressedCnt != 0) {                                                        \
136             ((void)HILOG_IMPL((type), (level), ANS_LOG_DOMAIN, ANS_REMINDER_LOG_TAG,    \
137             "[%{public}s(%{public}s:%{public}d)]log suppressed cnt %{public}u",         \
138             CUR_FILENAME, __FUNCTION__, __LINE__, supressedCnt));                       \
139         }                                                                               \
140         (canPrint) = true;                                                              \
141     } else {                                                                            \
142         supressed++;                                                                    \
143         (canPrint) = false;                                                             \
144     }                                                                                   \
145 } while (0)
146 
147 #define ANS_LOGF_LIMIT(fmt, ...)                                        \
148 do {                                                                    \
149     bool can = true;                                                    \
150     ANS_PRINT_LIMIT(LOG_CORE, LOG_FATAL, ANS_LOG_LIMIT_INTERVALS, can); \
151     if (can) {                                                          \
152         ANS_LOGF(fmt, ##__VA_ARGS__);                                   \
153     }                                                                   \
154 } while (0)
155 
156 #define ANS_LOGE_LIMIT(fmt, ...)                                        \
157 do {                                                                    \
158     bool can = true;                                                    \
159     ANS_PRINT_LIMIT(LOG_CORE, LOG_ERROR, ANS_LOG_LIMIT_INTERVALS, can); \
160     if (can) {                                                          \
161         ANS_LOGE(fmt, ##__VA_ARGS__);                                   \
162     }                                                                   \
163 } while (0)
164 
165 
166 #define ANS_LOGW_LIMIT(fmt, ...)                                        \
167 do {                                                                    \
168     bool can = true;                                                    \
169     ANS_PRINT_LIMIT(LOG_CORE, LOG_WARN, ANS_LOG_LIMIT_INTERVALS, can);  \
170     if (can) {                                                          \
171         ANS_LOGW(fmt, ##__VA_ARGS__);                                   \
172     }                                                                   \
173 } while (0)
174 
175 
176 #define ANS_LOGI_LIMIT(fmt, ...)                                        \
177 do {                                                                    \
178     bool can = true;                                                    \
179     ANS_PRINT_LIMIT(LOG_CORE, LOG_INFO, ANS_LOG_LIMIT_INTERVALS, can);  \
180     if (can) {                                                          \
181         ANS_LOGI(fmt, ##__VA_ARGS__);                                   \
182     }                                                                   \
183 } while (0)
184 
185 #define ANS_LOGD_LIMIT(fmt, ...)                                        \
186 do {                                                                    \
187     bool can = true;                                                    \
188     ANS_PRINT_LIMIT(LOG_CORE, LOG_DEBUG, ANS_LOG_LIMIT_INTERVALS, can); \
189     if (can) {                                                          \
190         ANS_LOGD(fmt, ##__VA_ARGS__);                                   \
191     }                                                                   \
192 } while (0)
193 }  // namespace Notification
194 }  // namespace OHOS
195 #endif  // BASE_NOTIFICATION_ANS_STANDARD_INNERKITS_BASE_INCLUDE_ANS_LOG_HELPER_H
196