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