1 #ifndef API_LUME_LOG_H
2 #define API_LUME_LOG_H
3 
4 /*
5  * Copyright (C) 2023 Huawei Device Co., Ltd.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <cassert>
20 #include <memory>
21 
22 // NOTE: LUME_ONCE is meant e.g. to prevent excessive flooding in the logs with repeating errors.
23 // i.e. It's not meant for normal working code.
24 #define LUME_ONCE(uniqueId, runOnce) { if (lume::CheckOnce(uniqueId)) { runOnce; } }
25 #define LUME_ONCE_RESET lume::CheckOnceReset
26 
27 #define LUME_UNUSED(x) (void)(x)
28 #define LUME_STATIC_ASSERT(expression) static_assert(expression)
29 
30 #ifndef NDEBUG
31 #define LUME_ASSERT(expression) assert(lume::getLogger().logAssert(__FILE__, __LINE__, !!(expression), #expression, ""))
32 #define LUME_ASSERT_MSG(expression, ...) assert(lume::getLogger().logAssert(__FILE__, __LINE__, !!(expression), #expression, __VA_ARGS__))
33 #else
34 #define LUME_ASSERT(...)
35 #define LUME_ASSERT_MSG(...)
36 #endif
37 
38 // Enabling warnings checks for format string parameters.
39 #if defined(__clang__)
40 #define FORMAT_FUNC(formatPos, argsPos) __attribute__ ((__format__ (__printf__, formatPos, argsPos)))
41 #define FORMAT_ATTRIBUTE
42 #elif defined(__GNUC__)
43 #define FORMAT_FUNC(formatPos, argsPos) __attribute__ ((format (printf, formatPos, argsPos)))
44 #define FORMAT_ATTRIBUTE
45 #elif defined(_MSC_VER)
46 #define FORMAT_FUNC(...)
47 #define FORMAT_ATTRIBUTE _In_z_ _Printf_format_string_
48 #else
49 #define FORMAT_FUNC
50 #define FORMAT_ATTRIBUTE
51 #endif
52 
53 #if defined(LUME_LOG_NO_DEBUG)
54 #define LUME_LOG_V(...)
55 #define LUME_LOG_D(...)
56 #define LUME_LOG_I(...) lume::getLogger().log(lume::ILogger::LogLevel::Info, nullptr, 0, __VA_ARGS__)
57 #define LUME_LOG_W(...) lume::getLogger().log(lume::ILogger::LogLevel::Warning, nullptr, 0, __VA_ARGS__)
58 #define LUME_LOG_E(...) lume::getLogger().log(lume::ILogger::LogLevel::Error, nullptr, 0, __VA_ARGS__)
59 #define LUME_LOG_F(...) lume::getLogger().log(lume::ILogger::LogLevel::Fatal, nullptr, 0, __VA_ARGS__)
60 #define LUME_LOG_ONCE_V(...)
61 #define LUME_LOG_ONCE_D(...)
62 #define LUME_LOG_ONCE_I(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_I(__VA_ARGS__))
63 #define LUME_LOG_ONCE_W(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_W(__VA_ARGS__))
64 #define LUME_LOG_ONCE_E(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_E(__VA_ARGS__))
65 #define LUME_LOG_ONCE_F(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_F(__VA_ARGS__))
66 
67 #elif defined(LUME_LOG_DISABLED)
68 #define LUME_LOG_V(...)
69 #define LUME_LOG_D(...)
70 #define LUME_LOG_I(...)
71 #define LUME_LOG_W(...)
72 #define LUME_LOG_E(...)
73 #define LUME_LOG_F(...)
74 #define LUME_LOG_ONCE_V(...)
75 #define LUME_LOG_ONCE_D(...)
76 #define LUME_LOG_ONCE_I(...)
77 #define LUME_LOG_ONCE_W(...)
78 #define LUME_LOG_ONCE_E(...)
79 #define LUME_LOG_ONCE_F(...)
80 
81 #else
82 #define LUME_LOG_V(...) lume::getLogger().log(lume::ILogger::LogLevel::Verbose, __FILE__, __LINE__, __VA_ARGS__)
83 #define LUME_LOG_D(...) lume::getLogger().log(lume::ILogger::LogLevel::Debug, __FILE__, __LINE__, __VA_ARGS__)
84 #define LUME_LOG_I(...) lume::getLogger().log(lume::ILogger::LogLevel::Info, __FILE__, __LINE__, __VA_ARGS__)
85 #define LUME_LOG_W(...) lume::getLogger().log(lume::ILogger::LogLevel::Warning, __FILE__, __LINE__, __VA_ARGS__)
86 #define LUME_LOG_E(...) lume::getLogger().log(lume::ILogger::LogLevel::Error, __FILE__, __LINE__, __VA_ARGS__)
87 #define LUME_LOG_F(...) lume::getLogger().log(lume::ILogger::LogLevel::Fatal, __FILE__, __LINE__, __VA_ARGS__)
88 #define LUME_LOG_ONCE_V(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_V(__VA_ARGS__))
89 #define LUME_LOG_ONCE_D(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_D(__VA_ARGS__))
90 #define LUME_LOG_ONCE_I(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_I(__VA_ARGS__))
91 #define LUME_LOG_ONCE_W(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_W(__VA_ARGS__))
92 #define LUME_LOG_ONCE_E(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_E(__VA_ARGS__))
93 #define LUME_LOG_ONCE_F(uniqueId, ...) LUME_ONCE(uniqueId, LUME_LOG_F(__VA_ARGS__))
94 #endif
95 
96 
97 namespace lume
98 {
99 
100 class ILogger
101 {
102 public:
103 
104     enum class LogLevel
105     {
106         Verbose = 0,
107         Debug,
108         Info,
109         Warning,
110         Error,
111         Fatal,
112 
113         // This level should only be used when setting the log level filter with setLogLevel(),
114         // not as a log level for a message.
115         None,
116     };
117 
118     class IOutput
119     {
120     public:
121         virtual ~IOutput() = default;
122         virtual void write(LogLevel aLogLevel, const char *aFilename, int aLinenumber, const char *aMessage) = 0;
123     };
124 
125     ILogger() = default;
126     virtual ~ILogger() = default;
127 
128     ILogger(ILogger const&) = delete;
129     void operator=(ILogger const&) = delete;
130 
131 
132     virtual void VLog(LogLevel aLogLevel,
133         const char *aFilename, int aLinenumber, const char *aFormat, va_list aArgs) = 0;
134     virtual FORMAT_FUNC(5, 6) void log(LogLevel aLogLevel, const char *aFilename, int aLinenumber, FORMAT_ATTRIBUTE const char *aFormat, ...) = 0;
135     virtual FORMAT_FUNC(6, 7) bool logAssert(const char *aFilename, int aLinenumber, bool expression, const char *expressionString, FORMAT_ATTRIBUTE const char *aFormat, ...) = 0;
136 
137     virtual LogLevel  getLogLevel() const = 0;
138     virtual void setLogLevel(LogLevel aLogLevel) = 0;
139 
140     virtual void addOutput(std::unique_ptr<IOutput> aOutput) = 0;
141 };
142 
143 /*LUME_PUBLIC*/ ILogger &getLogger();
144 
145 std::unique_ptr<ILogger::IOutput> createLoggerConsoleOutput();
146 std::unique_ptr<ILogger::IOutput> createLoggerDebugOutput();
147 std::unique_ptr<ILogger::IOutput> createLoggerFileOutput(const char *aFilename);
148 
149 
150 bool CheckOnce(const char *aId);
151 void CheckOnceReset();
152 
153 
154 } // lume
155 
156 #endif // API_LUME_LOG_H
157