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 API_CORE_ILOGGER_H
17 #define API_CORE_ILOGGER_H
18
19 #include <cstdarg>
20
21 #include <base/containers/string_view.h>
22 #include <base/containers/unique_ptr.h>
23 #include <base/namespace.h>
24 #include <base/util/uid.h>
25 #include <core/namespace.h>
26 #include <core/plugin/intf_interface.h>
27
28 // Enabling warnings checks for format string parameters.
29 #if defined(__clang__)
30 #define FORMAT_FUNC(formatPos, argsPos) __attribute__((__format__(__printf__, formatPos, argsPos)))
31 #define FORMAT_ATTRIBUTE
32 #define CHECK_FORMAT_STRING(...) ((void)0)
33 #elif defined(__GNUC__)
34 #define FORMAT_FUNC(formatPos, argsPos) __attribute__((format(printf, formatPos, argsPos)))
35 #define FORMAT_ATTRIBUTE
36 #define CHECK_FORMAT_STRING(...) ((void)0)
37 #elif defined(_MSC_VER)
38 #define FORMAT_FUNC(...)
39 #define FORMAT_ATTRIBUTE _In_z_ _Printf_format_string_
40 // Hack to force format string verifying during compile time. see
41 // https://devblogs.microsoft.com/cppblog/format-specifiers-checking/ Note that the snprintf should never be evaluated
42 // during runtime due to the use of "false &&" (dead-code elimination works on debug too)
43 #define CHECK_FORMAT_STRING(...) (false && _snprintf_s(nullptr, 0, 0, ##__VA_ARGS__))
44 #else
45 #define FORMAT_FUNC
46 #define FORMAT_ATTRIBUTE
47 #define CHECK_FORMAT_STRING(...) ((void)0)
48 #endif
49
CORE_BEGIN_NAMESPACE()50 CORE_BEGIN_NAMESPACE()
51 /** @ingroup group_log */
52 /** Logger */
53 class ILogger : public IInterface {
54 public:
55 static constexpr auto UID = BASE_NS::Uid { "d9c55b07-441c-4059-909b-88ebc3c07b1e" };
56
57 /** Logging level */
58 enum class LogLevel {
59 /** Verbose */
60 LOG_VERBOSE = 0,
61 /** Debug */
62 LOG_DEBUG,
63 /** Info */
64 LOG_INFO,
65 /** Warning */
66 LOG_WARNING,
67 /** Error */
68 LOG_ERROR,
69 /** Fatal */
70 LOG_FATAL,
71
72 // This level should only be used when setting the log level filter with SetLogLevel(),
73 // not as a log level for a message.
74 /** None */
75 LOG_NONE,
76 };
77
78 /** Output */
79 class IOutput {
80 public:
81 /** Write */
82 virtual void Write(
83 LogLevel logLevel, BASE_NS::string_view filename, int lineNumber, BASE_NS::string_view message) = 0;
84
85 struct Deleter {
86 constexpr Deleter() noexcept = default;
87 void operator()(IOutput* ptr) const
88 {
89 ptr->Destroy();
90 }
91 };
92 using Ptr = BASE_NS::unique_ptr<IOutput, Deleter>;
93
94 protected:
95 IOutput() = default;
96 virtual ~IOutput() = default;
97 virtual void Destroy() = 0;
98 };
99
100 /** Write to log (Version of logger that takes va_list, please use macros instead) */
101 virtual void VLog(LogLevel logLevel, BASE_NS::string_view filename, int lineNumber, BASE_NS::string_view format,
102 std::va_list args) = 0;
103 /** Write to log once (Version of logger that takes va_list, please use macros instead) */
104 virtual void VLogOnce(BASE_NS::string_view id, LogLevel logLevel, BASE_NS::string_view filename, int lineNumber,
105 BASE_NS::string_view format, std::va_list args) = 0;
106 virtual bool VLogAssert(BASE_NS::string_view filename, int lineNumber, bool expression,
107 BASE_NS::string_view expressionString, BASE_NS::string_view format, std::va_list args) = 0;
108
109 /** Write to log (Takes var args) */
110 virtual FORMAT_FUNC(5, 6) void Log(
111 LogLevel logLevel, BASE_NS::string_view filename, int lineNumber, FORMAT_ATTRIBUTE const char* format, ...) = 0;
112 /** Write to log (Version which is used with asserts) */
113 virtual FORMAT_FUNC(6, 7) bool LogAssert(BASE_NS::string_view filename, int lineNumber, bool expression,
114 BASE_NS::string_view expressionString, FORMAT_ATTRIBUTE const char* format, ...) = 0;
115
116 /** Get log level */
117 virtual LogLevel GetLogLevel() const = 0;
118 /** Set log level */
119 virtual void SetLogLevel(LogLevel logLevel) = 0;
120
121 /** Add output (for custom loggers) */
122 virtual void AddOutput(IOutput::Ptr output) = 0;
123
124 /** resets all "logOnce" handles. allowing the messages to be logged again */
125 virtual void CheckOnceReset() = 0;
126
127 protected:
128 ILogger() = default;
129 virtual ~ILogger() = default;
130
131 ILogger(ILogger const&) = delete;
132 void operator=(ILogger const&) = delete;
133 };
134
GetName(const ILogger *)135 inline constexpr BASE_NS::string_view GetName(const ILogger*)
136 {
137 return "ILogger";
138 }
139
140 /** @} */
141 CORE_END_NAMESPACE()
142 #endif // API_CORE_ILOGGER_H
143