1 /*
2  * Copyright (c) 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 TEXT_LOG_H
17 #define TEXT_LOG_H
18 
19 #ifdef OHOS_TEXT_ENABLE
20 #include <hilog/log.h>
21 #endif
22 
23 namespace OHOS {
24 namespace Rosen {
25 
26 #ifdef OHOS_TEXT_ENABLE
27 
28 #undef LOG_DOMAIN
29 #define LOG_DOMAIN 0xD001408
30 
31 #undef LOG_TAG
32 #define LOG_TAG "Text"
33 
34 #define TEXT_LOG_LIMIT_HOURS 3600
35 #define TEXT_LOG_LIMIT_MINUTE 60
36 #define TEXT_LOG_LIMIT_PRINT_FREQUENCY 3
37 
38 #define TEXT_LOGD(fmt, ...)              \
39     HILOG_DEBUG(LOG_CORE, "%{public}s: " fmt, __func__, ##__VA_ARGS__)
40 #define TEXT_LOGI(fmt, ...)              \
41     HILOG_INFO(LOG_CORE, "%{public}s: " fmt, __func__, ##__VA_ARGS__)
42 #define TEXT_LOGW(fmt, ...)              \
43     HILOG_WARN(LOG_CORE, "%{public}s: " fmt, __func__, ##__VA_ARGS__)
44 #define TEXT_LOGE(fmt, ...)              \
45     HILOG_ERROR(LOG_CORE, "%{public}s: " fmt, __func__, ##__VA_ARGS__)
46 
47 #define TEXT_PRINT_LIMIT(type, level, intervals, canPrint, frequency)                                    \
48     do {                                                                                                 \
49         static auto last = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>();   \
50         static uint32_t supressed = 0;                                                                   \
51         static int printCount = 0;                                                                       \
52         auto now = std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()); \
53         auto duration = now - last;                                                                      \
54         if (duration.count() >= (intervals)) {                                                           \
55             last = now;                                                                                  \
56             uint32_t supressedCnt = supressed;                                                           \
57             supressed = 0;                                                                               \
58             printCount = 1;                                                                              \
59             if (supressedCnt != 0) {                                                                     \
60                 ((void)HILOG_IMPL((type), (level), LOG_DOMAIN, LOG_TAG,                                  \
61                     "%{public}s log suppressed cnt %{public}u", __func__, supressedCnt));                \
62             }                                                                                            \
63             (canPrint) = true;                                                                           \
64         } else {                                                                                         \
65             if ((printCount++) < (frequency)) {                                                          \
66                 (canPrint) = true;                                                                       \
67             } else {                                                                                     \
68                 supressed++;                                                                             \
69                 (canPrint) = false;                                                                      \
70             }                                                                                            \
71         }                                                                                                \
72     } while (0)
73 
74 #define TEXT_LOGI_LIMIT3_HOUR(fmt, ...)                                                                  \
75     do {                                                                                                 \
76         bool can = true;                                                                                 \
77         TEXT_LOGD(fmt, ##__VA_ARGS__);                                                                   \
78         TEXT_PRINT_LIMIT(LOG_CORE, LOG_INFO, TEXT_LOG_LIMIT_HOURS, can, TEXT_LOG_LIMIT_PRINT_FREQUENCY); \
79         if (can) {                                                                                       \
80             TEXT_LOGI(fmt, ##__VA_ARGS__);                                                               \
81         }                                                                                                \
82     } while (0)
83 
84 #define TEXT_LOGW_LIMIT3_HOUR(fmt, ...)                                                                  \
85     do {                                                                                                 \
86         bool can = true;                                                                                 \
87         TEXT_LOGD(fmt, ##__VA_ARGS__);                                                                   \
88         TEXT_PRINT_LIMIT(LOG_CORE, LOG_WARN, TEXT_LOG_LIMIT_HOURS, can, TEXT_LOG_LIMIT_PRINT_FREQUENCY); \
89         if (can) {                                                                                       \
90             TEXT_LOGW(fmt, ##__VA_ARGS__);                                                               \
91         }                                                                                                \
92     } while (0)
93 
94 #define TEXT_LOGE_LIMIT3_HOUR(fmt, ...)                                                                   \
95     do {                                                                                                  \
96         bool can = true;                                                                                  \
97         TEXT_LOGD(fmt, ##__VA_ARGS__);                                                                    \
98         TEXT_PRINT_LIMIT(LOG_CORE, LOG_ERROR, TEXT_LOG_LIMIT_HOURS, can, TEXT_LOG_LIMIT_PRINT_FREQUENCY); \
99         if (can) {                                                                                        \
100             TEXT_LOGE(fmt, ##__VA_ARGS__);                                                                \
101         }                                                                                                 \
102     } while (0)
103 
104 #define TEXT_LOGI_LIMIT3_MIN(fmt, ...)                                                                    \
105     do {                                                                                                  \
106         bool can = true;                                                                                  \
107         TEXT_LOGD(fmt, ##__VA_ARGS__);                                                                    \
108         TEXT_PRINT_LIMIT(LOG_CORE, LOG_INFO, TEXT_LOG_LIMIT_MINUTE, can, TEXT_LOG_LIMIT_PRINT_FREQUENCY); \
109         if (can) {                                                                                        \
110             TEXT_LOGI(fmt, ##__VA_ARGS__);                                                                \
111         }                                                                                                 \
112     } while (0)
113 
114 #define TEXT_LOGW_LIMIT3_MIN(fmt, ...)                                                                    \
115     do {                                                                                                  \
116         bool can = true;                                                                                  \
117         TEXT_LOGD(fmt, ##__VA_ARGS__);                                                                    \
118         TEXT_PRINT_LIMIT(LOG_CORE, LOG_WARN, TEXT_LOG_LIMIT_MINUTE, can, TEXT_LOG_LIMIT_PRINT_FREQUENCY); \
119         if (can) {                                                                                        \
120             TEXT_LOGW(fmt, ##__VA_ARGS__);                                                                \
121         }                                                                                                 \
122     } while (0)
123 
124 #define TEXT_LOGE_LIMIT3_MIN(fmt, ...)                                                                     \
125     do {                                                                                                   \
126         bool can = true;                                                                                   \
127         TEXT_LOGD(fmt, ##__VA_ARGS__);                                                                     \
128         TEXT_PRINT_LIMIT(LOG_CORE, LOG_ERROR, TEXT_LOG_LIMIT_MINUTE, can, TEXT_LOG_LIMIT_PRINT_FREQUENCY); \
129         if (can) {                                                                                         \
130             TEXT_LOGE(fmt, ##__VA_ARGS__);                                                                 \
131         }                                                                                                  \
132     } while (0)
133 
134 #else
135 #define TEXT_LOGD(fmt, ...)
136 #define TEXT_LOGI(fmt, ...)
137 #define TEXT_LOGW(fmt, ...)
138 #define TEXT_LOGE(fmt, ...)
139 
140 #define TEXT_LOGI_LIMIT3_HOUR(fmt, ...)
141 #define TEXT_LOGW_LIMIT3_HOUR(fmt, ...)
142 #define TEXT_LOGE_LIMIT3_HOUR(fmt, ...)
143 
144 #define TEXT_LOGI_LIMIT3_MIN(fmt, ...)
145 #define TEXT_LOGW_LIMIT3_MIN(fmt, ...)
146 #define TEXT_LOGE_LIMIT3_MIN(fmt, ...)
147 
148 #endif
149 
150 #define TEXT_ERROR_CHECK(ret, statement, format, ...)  \
151     do {                                               \
152         if (!(ret)) {                                  \
153             TEXT_LOGE(format, ##__VA_ARGS__);          \
154             statement;                                 \
155         }                                              \
156     } while (0)
157 
158 #define TEXT_INFO_CHECK(ret, statement, format, ...)   \
159     do {                                               \
160         if (!(ret)) {                                  \
161             TEXT_LOGI(format, ##__VA_ARGS__);          \
162             statement;                                 \
163         }                                              \
164     } while (0)
165 
166 #define TEXT_CHECK(ret, statement)                     \
167     do {                                               \
168         if (!(ret)) {                                  \
169             statement;                                 \
170         }                                              \
171     } while (0)
172 
173 #define TEXT_CHECK_RETURN_VALUE(ret, result)           \
174     do {                                               \
175         if (!(ret)) {                                  \
176             return result;                             \
177         }                                              \
178     } while (0)
179 
180 
181 } // namespace Rosen
182 } // namespace OHOS
183 #endif
184