ifw-fnd 2.0.1
 
Loading...
Searching...
No Matches
logger.hpp
Go to the documentation of this file.
1
26
27#pragma once
28
29#include <chrono>
30#include <memory>
31#include <string>
32#include <string_view>
33#include <vector>
34
35#include <fmt/format.h>
36
37// FNDLOC: defined in <ifw/fnd/defs/base.hpp>, used by every FND* macro
38// below. NOT included here because base.hpp itself includes this header
39// (so its inline helpers can use FND* macros). Consumers should include
40// base.hpp instead of this header — it transitively pulls everything in.
41
42namespace ifw::fnd {
43
44 // Conventional logger name; kept for backwards compatibility with code
45 // that wants to embed it in messages or pass it to a concrete backend
46 // (e.g. when an InstallLogger() implementation routes to a named
47 // logger in CII or log4cplus).
48 static constexpr const char* IFW_FND_LOGGER_NAME = "ifwfnd";
49
55 enum class LogLevel : int {
56 TRACE = 0,
57 DEBUG = 10,
58 INFO = 20,
59 WARNING = 30,
60 ERROR = 40,
61 OFF = 100,
62 };
63
77 class Logger {
78 public:
79 Logger() = default;
80 virtual ~Logger() = default;
81
82 Logger(const Logger&) = delete;
83 Logger& operator=(const Logger&) = delete;
84 Logger(Logger&&) = delete;
85 Logger& operator=(Logger&&) = delete;
86
92 virtual void Emit(LogLevel level, const std::string& message) = 0;
93
101 virtual void Throw(const std::string& message);
102
123 virtual std::vector<std::string> ListSources() const {
124 return {};
125 }
126
127 void SetLogLevel(LogLevel level) noexcept { m_level = level; }
128 LogLevel GetLogLevel() const noexcept { return m_level; }
129
135 void Trace (const std::string& m) { Emit(LogLevel::TRACE, m); }
136 void Debug (const std::string& m) { Emit(LogLevel::DEBUG, m); }
137 void Info (const std::string& m) { Emit(LogLevel::INFO, m); }
138 void Warning(const std::string& m) { Emit(LogLevel::WARNING, m); }
139 void Error (const std::string& m) { Emit(LogLevel::ERROR, m); }
141
142 protected:
144 };
145
151 void InstallLogger(std::unique_ptr<Logger> logger) noexcept;
152
155 Logger& Log();
156
161 bool HasLogger() noexcept;
162
167 std::unique_ptr<Logger> MakeStdoutLogger();
168
173 std::unique_ptr<Logger> MakeNullLogger();
174
180 std::string_view LogLevelName(LogLevel level) noexcept;
181
188 inline std::string TraceExtra() {
189 return {};
190 }
191 template <typename... Args>
192 inline std::string TraceExtra(fmt::string_view fmt_str, Args&&... args) {
193 return ": " + fmt::vformat(fmt_str, fmt::make_format_args(args...));
194 }
195
214 public:
215 ScopedTracer(std::string location,
216 std::string extra) noexcept;
218
219 ScopedTracer(const ScopedTracer&) = delete;
223
224 private:
225 const std::chrono::steady_clock::time_point m_entry;
226 const std::string m_location;
227 const std::string m_extra;
228 const bool m_active;
229 };
230
231} // namespace ifw::fnd
232
233// FNDLOC is pulled in via the base.hpp include above. The FND* macros
234// below use it.
235
249
250#define FND_LOG_IMPL_(level_, fmt_str_, ...) \
251 do { \
252 auto& _fnd_log = ::ifw::fnd::Log(); \
253 if (_fnd_log.GetLogLevel() <= (level_)) { \
254 _fnd_log.Emit((level_), \
255 FNDLOC + ": " + \
256 ::fmt::format( \
257 ::fmt::runtime(std::string(fmt_str_)) \
258 __VA_OPT__(,) __VA_ARGS__)); \
259 } \
260 } while (0)
261
287#define FND_TRACE_NAME_(line) _fnd_trace_##line
288#define FND_TRACE_NAME(line) FND_TRACE_NAME_(line)
289
290#define FNDTRACE(...) \
291 [[maybe_unused]] ::ifw::fnd::ScopedTracer FND_TRACE_NAME(__LINE__) { \
292 (::ifw::fnd::HasLogger() && \
293 ::ifw::fnd::Log().GetLogLevel() <= ::ifw::fnd::LogLevel::TRACE) \
294 ? (FNDLOC + ": " + std::string(__PRETTY_FUNCTION__)) \
295 : std::string{}, \
296 (::ifw::fnd::HasLogger() && \
297 ::ifw::fnd::Log().GetLogLevel() <= ::ifw::fnd::LogLevel::TRACE) \
298 ? ::ifw::fnd::TraceExtra(__VA_ARGS__) \
299 : std::string{} \
300 }
301
302#define FNDDEBUG(fmt_str, ...) \
303 FND_LOG_IMPL_(::ifw::fnd::LogLevel::DEBUG, fmt_str __VA_OPT__(,) __VA_ARGS__)
304
305#define FNDINFO(fmt_str, ...) \
306 FND_LOG_IMPL_(::ifw::fnd::LogLevel::INFO, fmt_str __VA_OPT__(,) __VA_ARGS__)
307
308#define FNDWARNING(fmt_str, ...) \
309 FND_LOG_IMPL_(::ifw::fnd::LogLevel::WARNING, fmt_str __VA_OPT__(,) __VA_ARGS__)
310
311#define FNDERROR(fmt_str, ...) \
312 FND_LOG_IMPL_(::ifw::fnd::LogLevel::ERROR, fmt_str __VA_OPT__(,) __VA_ARGS__)
313
314#define FNDTHROW(fmt_str, ...) \
315 do { \
316 ::ifw::fnd::Log().Throw( \
317 FNDLOC + ": " + \
318 ::fmt::format( \
319 ::fmt::runtime(std::string(fmt_str)) \
320 __VA_OPT__(,) __VA_ARGS__)); \
321 } while (0)
322
Logger(const Logger &)=delete
void Error(const std::string &m)
Definition logger.hpp:139
Logger()=default
void Debug(const std::string &m)
Definition logger.hpp:136
void Info(const std::string &m)
Definition logger.hpp:137
void SetLogLevel(LogLevel level) noexcept
Definition logger.hpp:127
void Warning(const std::string &m)
Definition logger.hpp:138
Logger(Logger &&)=delete
Logger & operator=(Logger &&)=delete
LogLevel m_level
Definition logger.hpp:143
virtual ~Logger()=default
void Trace(const std::string &m)
Definition logger.hpp:135
virtual std::vector< std::string > ListSources() const
Enumerate the named log sources this backend knows about.
Definition logger.hpp:123
virtual void Throw(const std::string &message)
Log at error level and then throw.
Definition defs.cpp:110
virtual void Emit(LogLevel level, const std::string &message)=0
Deliver one already-formatted log line.
LogLevel GetLogLevel() const noexcept
Definition logger.hpp:128
Logger & operator=(const Logger &)=delete
ScopedTracer & operator=(ScopedTracer &&)=delete
ScopedTracer(std::string location, std::string extra) noexcept
Definition defs.cpp:171
ScopedTracer & operator=(const ScopedTracer &)=delete
ScopedTracer(const ScopedTracer &)=delete
ScopedTracer(ScopedTracer &&)=delete
~ScopedTracer()
Definition defs.cpp:189
This source file contains definitions of the types and constants to handle data types.
Definition defs.cpp:28
LogLevel
Log severity, lowest to highest.
Definition logger.hpp:55
@ WARNING
Definition logger.hpp:59
@ TRACE
Definition logger.hpp:56
@ INFO
Definition logger.hpp:58
@ OFF
Definition logger.hpp:61
@ ERROR
Definition logger.hpp:60
@ DEBUG
Definition logger.hpp:57
std::string TraceExtra()
Helper used by FNDTRACE.
Definition logger.hpp:188
std::unique_ptr< Logger > MakeStdoutLogger()
Factory: a logger that prints to stdout.
Definition defs.cpp:135
Logger & Log()
Access the installed logger.
Definition defs.cpp:120
bool HasLogger() noexcept
true iff a logger has been installed.
Definition defs.cpp:131
std::unique_ptr< Logger > MakeNullLogger()
Factory: a logger that discards everything.
Definition defs.cpp:139
void InstallLogger(std::unique_ptr< Logger > logger) noexcept
Install the process-wide logger.
Definition defs.cpp:115
std::string_view LogLevelName(LogLevel level) noexcept
Render a LogLevel as a short uppercase string.
Definition defs.cpp:143