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