Creates a Logger class which can be used to log messages
Used for logging is class LogData which has a templated << operator to receive data the same way as known from std::cout printing: << "logmessage: " << 1
Interface for Outputters and two implementations - console and file - which can be appended to route log messages. These Outputters also format the log message
Macros, init functions, namespace weblog
Various
1. Logger class
Logger class is implemented as singleton. This means there should only be one instantiation and it is globally accessible. This is called an anti-pattern almost everywhere, except for very specific cases - like for example logging.
The Logger::getInstance() has a static instance of the Logger and returns it. The first time calling this function the Logger will be constructed. Each call after will just return the reference.
Logger has a LogLevel which can be DEBUG, INFO, WARN, ERROR.
Logger has a vector of ILogOutputters, to register different Outputters (like console or file)
Logger::init can be used to set LogLevel and Outputter
The Logger receives its log via an overload of the += operator. It can receive a class LogData, which it will then pass onto all its registered Outputters
2. LogData class
Container to hold LogData
timestamp : created in ctor
message : can be appended with <<
LogLevel
Name of function : passed via compiler macro
Line in the file : passed via compiler macro
Name of file : passed via compiler macro
3. ILogOutputter Interface
Defines a LogOutputter
log() writes the message somewhere
getFormattedMessage() constructs the message via the LogData
Two implementations: LogOutputterConsole and LogOutputterFile
Console: prints with color to std::clog or std::cerr depending on LogLevel
File: opens file and appends to it. Filename gets passed in ctor
Outputters need to outlive Logger usage. Therefore their lifetime should also be static
4. Macros, Init, Namespace
Many logging libraries provide Macros for easier usage, followed this approach
Macros hides complicated call and makes it easier to use:
LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR
Usage: LOG_DEBUG << "Hello my " << 1 << "friend"
Two init functions to either init a file or console outputter. Both can be called to write to both, but every init function has one static Outputter -> two LogOutputterFile are not possible this way. But they can be appended via Logger::addLogOutputter
Everything is in namespace weblog
5. Various
Create sample implementation ofstream operator<< for ConfigFile, and its substructs. This way a ConfigFile config can be output like: LOG_DEBUG << config. Right now in LogConfigFile.cpp maybe other name? Needs to be updated if ConfigFile changes.
Create new make target comp. This runs make clean and then bear -- make to create a new compile_commands.json
Overview
1. Logger class
2. LogData class
3. ILogOutputter Interface
4. Macros, Init, Namespace
LOG_DEBUG << "Hello my " << 1 << "friend"
weblog
5. Various
LOG_DEBUG << config
. Right now in LogConfigFile.cpp maybe other name? Needs to be updated if ConfigFile changes.comp
. This runsmake clean
and thenbear -- make
to create a new compile_commands.jsonCloses #6