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 UTIL_PLUGIN_LOG_H
16 #define UTIL_PLUGIN_LOG_H
17 
18 #include <cassert>
19 #include <cstdarg>
20 
21 #include <core/implementation_uids.h>
22 #include <core/intf_logger.h>
23 #include <core/plugin/intf_class_register.h>
24 #include <render/namespace.h>
25 
26 #define PLUGIN_ONCE_RESET RENDER_NS::PluginCheckOnceReset
27 
28 #define PLUGIN_UNUSED(x) (void)(x)
29 #define PLUGIN_STATIC_ASSERT(expression) static_assert(!!(expression))
30 
31 #ifndef NDEBUG
32 #define PLUGIN_FILE_INFO __FILE__, __LINE__
33 #define PLUGIN_ASSERT(expression) \
34     assert(!!(expression) || RENDER_NS::PluginLogAssert(PLUGIN_FILE_INFO, !!(expression), #expression, ""))
35 #define PLUGIN_ASSERT_MSG(expression, ...) \
36     assert(!!(expression) || RENDER_NS::PluginLogAssert(PLUGIN_FILE_INFO, !!(expression), #expression, __VA_ARGS__))
37 #else
38 #define PLUGIN_FILE_INFO "", 0U
39 #define PLUGIN_ASSERT(...)
40 #define PLUGIN_ASSERT_MSG(...)
41 #endif
42 
43 #if defined(PLUGIN_LOG_DISABLED) && (PLUGIN_LOG_DISABLED == 1)
44 #define PLUGIN_LOG_V(...)
45 #define PLUGIN_LOG_D(...)
46 #define PLUGIN_LOG_I(...)
47 #define PLUGIN_LOG_W(...)
48 #define PLUGIN_LOG_E(...)
49 #define PLUGIN_LOG_F(...)
50 #define PLUGIN_LOG_ONCE_V(...)
51 #define PLUGIN_LOG_ONCE_D(...)
52 #define PLUGIN_LOG_ONCE_I(...)
53 #define PLUGIN_LOG_ONCE_W(...)
54 #define PLUGIN_LOG_ONCE_E(...)
55 #define PLUGIN_LOG_ONCE_F(...)
56 
57 #else
58 
59 // Disable debug logs by default for release builds.
60 // PLUGIN_LOG_DEBUG compile option can be used to force debug logs also in release builds.
61 #if defined(NDEBUG) && !(defined(PLUGIN_LOG_DEBUG) && (PLUGIN_LOG_DEBUG == 1))
62 
63 #define PLUGIN_LOG_V(...)
64 #define PLUGIN_LOG_D(...)
65 #define PLUGIN_LOG_ONCE_V(...)
66 #define PLUGIN_LOG_ONCE_D(...)
67 #else
68 /** \addtogroup group_log
69  *  @{
70  */
71 /** Write message to log with verbose log level */
72 #define PLUGIN_LOG_V(...)             \
73     CHECK_FORMAT_STRING(__VA_ARGS__); \
74     RENDER_NS::PluginLog(CORE_NS::ILogger::LogLevel::LOG_VERBOSE, PLUGIN_FILE_INFO, __VA_ARGS__)
75 /** Write message to log with debug log level */
76 #define PLUGIN_LOG_D(...)             \
77     CHECK_FORMAT_STRING(__VA_ARGS__); \
78     RENDER_NS::PluginLog(CORE_NS::ILogger::LogLevel::LOG_DEBUG, PLUGIN_FILE_INFO, __VA_ARGS__)
79 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
80             i.e. It's not meant for normal working code. */
81 /** Write message to log with verbose log level */
82 #define PLUGIN_LOG_ONCE_V(uniqueId, ...) \
83     CHECK_FORMAT_STRING(__VA_ARGS__);    \
84     RENDER_NS::PluginLogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_VERBOSE, PLUGIN_FILE_INFO, __VA_ARGS__)
85 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
86             i.e. It's not meant for normal working code. */
87 /** Write message to log with debug log level */
88 #define PLUGIN_LOG_ONCE_D(uniqueId, ...) \
89     CHECK_FORMAT_STRING(__VA_ARGS__);    \
90     RENDER_NS::PluginLogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_DEBUG, PLUGIN_FILE_INFO, __VA_ARGS__)
91 #endif
92 
93 /** Write message to log with info log level */
94 #define PLUGIN_LOG_I(...)             \
95     CHECK_FORMAT_STRING(__VA_ARGS__); \
96     RENDER_NS::PluginLog(CORE_NS::ILogger::LogLevel::LOG_INFO, PLUGIN_FILE_INFO, __VA_ARGS__)
97 
98 /** Write message to log with warning log level */
99 #define PLUGIN_LOG_W(...)             \
100     CHECK_FORMAT_STRING(__VA_ARGS__); \
101     RENDER_NS::PluginLog(CORE_NS::ILogger::LogLevel::LOG_WARNING, PLUGIN_FILE_INFO, __VA_ARGS__)
102 
103 /** Write message to log with error log level */
104 #define PLUGIN_LOG_E(...)             \
105     CHECK_FORMAT_STRING(__VA_ARGS__); \
106     RENDER_NS::PluginLog(CORE_NS::ILogger::LogLevel::LOG_ERROR, PLUGIN_FILE_INFO, __VA_ARGS__)
107 
108 /** Write message to log with fatal log level */
109 #define PLUGIN_LOG_F(...)             \
110     CHECK_FORMAT_STRING(__VA_ARGS__); \
111     RENDER_NS::PluginLog(CORE_NS::ILogger::LogLevel::LOG_FATAL, PLUGIN_FILE_INFO, __VA_ARGS__)
112 
113 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
114             i.e. It's not meant for normal working code. */
115 /** Write message to log with info log level */
116 #define PLUGIN_LOG_ONCE_I(uniqueId, ...) \
117     CHECK_FORMAT_STRING(__VA_ARGS__);    \
118     RENDER_NS::PluginLogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_INFO, PLUGIN_FILE_INFO, __VA_ARGS__)
119 
120 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
121             i.e. It's not meant for normal working code. */
122 /** Write message to log with warning log level */
123 #define PLUGIN_LOG_ONCE_W(uniqueId, ...) \
124     CHECK_FORMAT_STRING(__VA_ARGS__);    \
125     RENDER_NS::PluginLogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_WARNING, PLUGIN_FILE_INFO, __VA_ARGS__)
126 
127 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
128             i.e. It's not meant for normal working code. */
129 /** Write message to log with error log level */
130 #define PLUGIN_LOG_ONCE_E(uniqueId, ...) \
131     CHECK_FORMAT_STRING(__VA_ARGS__);    \
132     RENDER_NS::PluginLogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_ERROR, PLUGIN_FILE_INFO, __VA_ARGS__)
133 
134 /** \brief NOTE: CORE_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
135             i.e. It's not meant for normal working code. */
136 /** Write message to log with fatal log level */
137 #define PLUGIN_LOG_ONCE_F(uniqueId, ...) \
138     CHECK_FORMAT_STRING(__VA_ARGS__);    \
139     RENDER_NS::PluginLogOnce(uniqueId, CORE_NS::ILogger::LogLevel::LOG_FATAL, PLUGIN_FILE_INFO, __VA_ARGS__)
140 #endif
141 
RENDER_BEGIN_NAMESPACE()142 RENDER_BEGIN_NAMESPACE()
143 inline CORE_NS::ILogger* GetPluginLogger()
144 {
145     static CORE_NS::ILogger* gPluginGlobalLogger { nullptr };
146     if (gPluginGlobalLogger == nullptr) {
147         gPluginGlobalLogger = CORE_NS::GetInstance<CORE_NS::ILogger>(CORE_NS::UID_LOGGER);
148     }
149     return gPluginGlobalLogger;
150 }
151 
PluginLog(CORE_NS::ILogger::LogLevel logLevel,const BASE_NS::string_view filename,int lineNumber,FORMAT_ATTRIBUTE const char * format,...)152 inline FORMAT_FUNC(4, 5) void PluginLog(CORE_NS::ILogger::LogLevel logLevel, const BASE_NS::string_view filename,
153     int lineNumber, FORMAT_ATTRIBUTE const char* format, ...)
154 {
155     // log manytimes
156     if (CORE_NS::ILogger* logger = GetPluginLogger(); logger) {
157         va_list vl;
158         va_start(vl, format);
159         logger->VLog(logLevel, filename, lineNumber, format, vl);
160         va_end(vl);
161     }
162 }
163 
PluginLogOnce(const BASE_NS::string_view id,CORE_NS::ILogger::LogLevel logLevel,const BASE_NS::string_view filename,int lineNumber,FORMAT_ATTRIBUTE const char * format,...)164 inline FORMAT_FUNC(5, 6) void PluginLogOnce(const BASE_NS::string_view id, CORE_NS::ILogger::LogLevel logLevel,
165     const BASE_NS::string_view filename, int lineNumber, FORMAT_ATTRIBUTE const char* format, ...)
166 {
167     // log once.
168     if (CORE_NS::ILogger* logger = GetPluginLogger(); logger) {
169         va_list vl;
170         va_start(vl, format);
171         logger->VLogOnce(id, logLevel, filename, lineNumber, format, vl);
172         va_end(vl);
173     }
174 }
175 
PluginLogAssert(const BASE_NS::string_view filename,int lineNumber,bool expression,const BASE_NS::string_view expressionString,FORMAT_ATTRIBUTE const char * format,...)176 inline FORMAT_FUNC(5, 6) bool PluginLogAssert(const BASE_NS::string_view filename, int lineNumber, bool expression,
177     const BASE_NS::string_view expressionString, FORMAT_ATTRIBUTE const char* format, ...)
178 {
179     if (!expression) {
180         if (CORE_NS::ILogger* logger = GetPluginLogger(); logger) {
181             va_list vl;
182             va_start(vl, format);
183             logger->VLogAssert(filename, lineNumber, expression, expressionString, format, vl);
184             va_end(vl);
185         }
186     }
187     return expression;
188 }
189 
PluginCheckOnceReset(const BASE_NS::string_view id)190 inline void PluginCheckOnceReset(const BASE_NS::string_view id)
191 {
192     // reset log once flag
193     if (CORE_NS::ILogger* logger = GetPluginLogger(); logger) {
194         logger->CheckOnceReset();
195     }
196 }
197 RENDER_END_NAMESPACE()
198 
199 #endif // UTIL_PLUGIN_LOG_H
200