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 #ifndef API_CORE_LOG_H
16 #define API_CORE_LOG_H
17
18 #include <cassert>
19 #include <cstdarg>
20
21 #include <base/containers/string_view.h>
22 #include <base/namespace.h>
23 #include <core/implementation_uids.h>
24 #include <core/intf_logger.h>
25 #include <core/namespace.h>
26 #include <core/plugin/intf_class_register.h>
27
28 #define CORE_ONCE_RESET CORE_NS::CheckOnceReset
29
30 #define CORE_UNUSED(x) (void)(x)
31 #define CORE_STATIC_ASSERT(expression) static_assert(expression)
32
33 #ifndef NDEBUG
34 #define CORE_ASSERT(expression) \
35 assert(!!(expression) || CORE_NS::LogAssert(__FILE__, __LINE__, !!(expression), #expression, ""))
36 #define CORE_ASSERT_MSG(expression, ...) \
37 assert(!!(expression) || CORE_NS::LogAssert(__FILE__, __LINE__, !!(expression), #expression, __VA_ARGS__))
38 #else
39 #define CORE_ASSERT(...) CORE_UNUSED(0)
40 #define CORE_ASSERT_MSG(...) CORE_UNUSED(0)
41 #endif
42
43 #if defined(CORE_LOG_DISABLED) && (CORE_LOG_DISABLED == 1)
44 #define CORE_LOG_V(...) CORE_UNUSED(0)
45 #define CORE_LOG_D(...) CORE_UNUSED(0)
46 #define CORE_LOG_I(...) CORE_UNUSED(0)
47 #define CORE_LOG_W(...) CORE_UNUSED(0)
48 #define CORE_LOG_E(...) CORE_UNUSED(0)
49 #define CORE_LOG_F(...) CORE_UNUSED(0)
50 #define CORE_LOG_ONCE_V(...) CORE_UNUSED(0)
51 #define CORE_LOG_ONCE_D(...) CORE_UNUSED(0)
52 #define CORE_LOG_ONCE_I(...) CORE_UNUSED(0)
53 #define CORE_LOG_ONCE_W(...) CORE_UNUSED(0)
54 #define CORE_LOG_ONCE_E(...) CORE_UNUSED(0)
55 #define CORE_LOG_ONCE_F(...) CORE_UNUSED(0)
56
57 // Disable debug logs by default for release builds.
58 // CORE_LOG_DEBUG compile option can be used to force debug logs also in release builds.
59 #elif defined(NDEBUG) && !(defined(CORE_LOG_DEBUG) && (CORE_LOG_DEBUG == 1))
60
61 #define CORE_LOG_V(...) CORE_UNUSED(0)
62
63 #define CORE_LOG_D(...) CORE_UNUSED(0)
64
65 #define CORE_LOG_I(...) \
66 CHECK_FORMAT_STRING(__VA_ARGS__), CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_INFO, "", 0, __VA_ARGS__)
67
68 #define CORE_LOG_W(...) \
69 CHECK_FORMAT_STRING(__VA_ARGS__), CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_WARNING, "", 0, __VA_ARGS__)
70
71 #define CORE_LOG_E(...) \
72 CHECK_FORMAT_STRING(__VA_ARGS__), CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_ERROR, "", 0, __VA_ARGS__)
73
74 #define CORE_LOG_F(...) \
75 CHECK_FORMAT_STRING(__VA_ARGS__), CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_FATAL, "", 0, __VA_ARGS__)
76
77 #define CORE_LOG_ONCE_V(...) CORE_UNUSED(0)
78
79 #define CORE_LOG_ONCE_D(...) CORE_UNUSED(0)
80
81 #define CORE_LOG_ONCE_I(uniqueId, ...) \
82 CHECK_FORMAT_STRING(__VA_ARGS__), \
83 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_INFO, "", 0, __VA_ARGS__)
84
85 #define CORE_LOG_ONCE_W(uniqueId, ...) \
86 CHECK_FORMAT_STRING(__VA_ARGS__), \
87 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_WARNING, "", 0, __VA_ARGS__);
88
89 #define CORE_LOG_ONCE_E(uniqueId, ...) \
90 CHECK_FORMAT_STRING(__VA_ARGS__), \
91 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_ERROR, "", 0, __VA_ARGS__)
92
93 #define CORE_LOG_ONCE_F(uniqueId, ...) \
94 CHECK_FORMAT_STRING(__VA_ARGS__), \
95 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_FATAL, "", 0, __VA_ARGS__)
96 #else
97 /** \addtogroup group_log
98 * @{
99 */
100 /** Write message to log with verbose log level */
101 #define CORE_LOG_V(...) \
102 CHECK_FORMAT_STRING(__VA_ARGS__), \
103 CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_VERBOSE, __FILE__, __LINE__, __VA_ARGS__)
104
105 /** Write message to log with debug log level */
106 #define CORE_LOG_D(...) \
107 CHECK_FORMAT_STRING(__VA_ARGS__), \
108 CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
109
110 /** Write message to log with info log level */
111 #define CORE_LOG_I(...) \
112 CHECK_FORMAT_STRING(__VA_ARGS__), \
113 CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
114
115 /** Write message to log with warning log level */
116 #define CORE_LOG_W(...) \
117 CHECK_FORMAT_STRING(__VA_ARGS__), \
118 CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_WARNING, __FILE__, __LINE__, __VA_ARGS__)
119
120 /** Write message to log with error log level */
121 #define CORE_LOG_E(...) \
122 CHECK_FORMAT_STRING(__VA_ARGS__), \
123 CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
124
125 /** Write message to log with fatal log level */
126 #define CORE_LOG_F(...) \
127 CHECK_FORMAT_STRING(__VA_ARGS__), \
128 CORE_NS::Log(CORE_NS::ILogger::LogLevel::LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
129
130 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
131 i.e. It's not meant for normal working code. */
132 /** Write message to log with verbose log level */
133 #define CORE_LOG_ONCE_V(uniqueId, ...) \
134 CHECK_FORMAT_STRING(__VA_ARGS__), \
135 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_VERBOSE, __FILE__, __LINE__, __VA_ARGS__)
136
137 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
138 i.e. It's not meant for normal working code. */
139 /** Write message to log with debug log level */
140 #define CORE_LOG_ONCE_D(uniqueId, ...) \
141 CHECK_FORMAT_STRING(__VA_ARGS__), \
142 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
143
144 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
145 i.e. It's not meant for normal working code. */
146 /** Write message to log with info log level */
147 #define CORE_LOG_ONCE_I(uniqueId, ...) \
148 CHECK_FORMAT_STRING(__VA_ARGS__), \
149 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
150
151 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
152 i.e. It's not meant for normal working code. */
153 /** Write message to log with warning log level */
154 #define CORE_LOG_ONCE_W(uniqueId, ...) \
155 CHECK_FORMAT_STRING(__VA_ARGS__), \
156 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_WARNING, __FILE__, __LINE__, __VA_ARGS__)
157
158 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
159 i.e. It's not meant for normal working code. */
160 /** Write message to log with error log level */
161 #define CORE_LOG_ONCE_E(uniqueId, ...) \
162 CHECK_FORMAT_STRING(__VA_ARGS__), \
163 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
164
165 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
166 i.e. It's not meant for normal working code. */
167 /** Write message to log with fatal log level */
168 #define CORE_LOG_ONCE_F(uniqueId, ...) \
169 CHECK_FORMAT_STRING(__VA_ARGS__), \
170 CORE_NS::LogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
171 #endif
172
CORE_BEGIN_NAMESPACE()173 CORE_BEGIN_NAMESPACE()
174 inline ILogger* GetLogger()
175 {
176 static ILogger* gGlobalLogger { nullptr };
177 if (gGlobalLogger == nullptr) {
178 gGlobalLogger = GetInstance<ILogger>(UID_LOGGER);
179 }
180 return gGlobalLogger;
181 }
182
Log(ILogger::LogLevel logLevel,const BASE_NS::string_view filename,int lineNumber,FORMAT_ATTRIBUTE const char * format,...)183 inline FORMAT_FUNC(4, 5) void Log(ILogger::LogLevel logLevel, const BASE_NS::string_view filename, int lineNumber,
184 FORMAT_ATTRIBUTE const char* format, ...)
185 {
186 // log manytimes
187 if (ILogger* logger = GetLogger(); logger) {
188 std::va_list vl;
189 va_start(vl, format);
190 logger->VLog(logLevel, filename, lineNumber, format, vl);
191 va_end(vl);
192 }
193 }
194
LogOnce(const BASE_NS::string_view id,ILogger::LogLevel logLevel,const BASE_NS::string_view filename,int lineNumber,FORMAT_ATTRIBUTE const char * format,...)195 inline FORMAT_FUNC(5, 6) void LogOnce(const BASE_NS::string_view id, ILogger::LogLevel logLevel,
196 const BASE_NS::string_view filename, int lineNumber, FORMAT_ATTRIBUTE const char* format, ...)
197 {
198 // log once.
199 if (ILogger* logger = GetLogger(); logger) {
200 std::va_list vl;
201 va_start(vl, format);
202 logger->VLogOnce(id, logLevel, filename, lineNumber, format, vl);
203 va_end(vl);
204 }
205 }
206
LogAssert(const BASE_NS::string_view filename,int lineNumber,bool expression,const BASE_NS::string_view expressionString,FORMAT_ATTRIBUTE const char * format,...)207 inline FORMAT_FUNC(5, 6) bool LogAssert(const BASE_NS::string_view filename, int lineNumber, bool expression,
208 const BASE_NS::string_view expressionString, FORMAT_ATTRIBUTE const char* format, ...)
209 {
210 if (!expression) {
211 if (ILogger* logger = GetLogger(); logger) {
212 std::va_list vl;
213 va_start(vl, format);
214 logger->VLogAssert(filename, lineNumber, expression, expressionString, format, vl);
215 va_end(vl);
216 }
217 }
218 return expression;
219 }
220
CheckOnceReset(const BASE_NS::string_view id)221 inline void CheckOnceReset(const BASE_NS::string_view id)
222 {
223 // reset log once flag
224 if (ILogger* logger = GetLogger(); logger) {
225 logger->CheckOnceReset();
226 }
227 }
228 /** @} */
229 CORE_END_NAMESPACE()
230 #endif // API_CORE_LOG_H
231