|
| Logger (LogLevel level, LogSink *sink) |
|
| ~Logger () |
|
bool | shouldLog (const LogCategory &category, LogLevel level) const |
|
template<class... Args> |
void | log (const LogCategory &category, LogLevel level, fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | trace (const LogCategory &category, fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | debug (const LogCategory &category, fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | info (const LogCategory &category, fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | warning (const LogCategory &category, fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | error (const LogCategory &category, fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | critical (const LogCategory &category, fmt::format_string< Args... > fmt, Args &&... args) |
|
bool | shouldLog (LogLevel level) const |
|
template<class... Args> |
void | log (LogLevel level, fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | trace (fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | debug (fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | info (fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | warning (fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | error (fmt::format_string< Args... > fmt, Args &&... args) |
|
template<class... Args> |
void | critical (fmt::format_string< Args... > fmt, Args &&... args) |
|
LogLevel | level () const |
|
void | setLevel (LogLevel level) |
|
std::optional< LogLevel > | level (const LogCategory &category) const |
|
void | setLevel (LogCategory &category, std::optional< LogLevel > level) |
|
LogSink * | sink () const |
|
void | setSink (LogSink *sink) |
|
Main logging class.
Logger
is a singleton, but the user is supposed to create a Logger
instance himself before using it. This would usually be done in the first few lines of main
.
Some notes on design decisions:
Logger
supports hooking into other logging frameworks, translating the log levels appropriately. Thus, it's possible to create separate LogCategory
instances for SDL and FFmpeg logs, and manage log levels through the Logger
interface. Setting global log level to LOG_CRITICAL
will then prevent both SDL and FFmpeg from emitting any non-critical log messages - the important point being that they will be filtered out at SDL/FFmpeg level, and not in the Logger
code.
- Point (1) above led to settling on making
Logger
a singleton. This is what pretty much all other logging libraries do, and thus supporting both multiple Logger
instances AND being able to hook into external logging frameworks made very little sense.
- This also made it possible to implement log categories efficiently by storing per-category log levels inside the
LogCategory
objects.
- Different logging targets are implemented with the
LogSink
interface. LogSink
also makes it possible to implement complex logging logic, i.e. writing all logs starting with LOG_DEBUG
into a file, but printing only errors to the console. It's up to the user to properly implement the log level handling in this case.