Continue on an article, Example.cpp parsing.
1. Set_pattern Custom Log format
Official reference: Https://github.com/gabime/spdlog/wiki/3.-Custom-formatting
You can format all the logs, or you can format the specified log, noting that Rotating_logger is a pointer variable in the code below.
auto rotating_logger = spd :: rotating_logger_mt ("some_logger_name", "logs / rotating.txt", 256, 2);
// Customize msg format for all messages
spd :: set_pattern ("*** [% H:% M:% S% z] [thread% t]% v ***");
rotating_logger-> info ("This is another message with custom format");
// Customize msg format for a specific logger object:
rotating_logger-> set_pattern ("[% H:% M:% S% f] [thread% t]% v ***");
Detailed format description is available on github, here is as follows:
2. set_level sets the log level
Logs below the set level will not be output. Sort by level, the higher the value, the higher the level:
// Runtime log levels
spd :: set_level (spd :: level :: info); // Set global log level to info
console-> debug ("This message should not be displayed!");
console-> set_level (spd :: level :: debug); // Set specific logger ‘s log level
console-> debug ("This message should be displayed ..");
The debug level of the first line log is lower than the set level info, and it will not be output when the level is info.
The debug level of the second line log is the same as the set level, so it can be displayed.
typedef enum
{
trace = 0,
debug = 1,
info = 2,
warn = 3,
err = 4,
critical = 5,
off = 6
} level_enum;
3. Modify the log output levels SPDLOG_TRACE and SPDLOG_DEBUG during the compilation phase
Official reference: https://github.com/gabime/spdlog/wiki/8.-Tweaking
When the macro definition SPDLOG_TRACE_ON is defined, you can use the SPDLOG_TRACE statement to output the trace level log, and the same is true for SPDLOG_DEBUG_ON.
#define SPDLOG_TRACE_ON
#define SPDLOG_DEBUG_ON
// Compile time log levels
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON
SPDLOG_TRACE (console, "Enabled only #ifdef SPDLOG_TRACE_ON .. {}, {}", 1, 3.23);
SPDLOG_DEBUG (console, "Enabled only #ifdef SPDLOG_DEBUG_ON .. {}, {}", 1, 3.23);
It should be noted that if you do not use the set_level command to set the log output level, the default level is the info level. At this time, even if these two macros are defined, debug and trace information will not be output. So you need to use set_level to set the level to trace first.
console-> set_level (spd :: level :: trace); // Set specific logger ‘s log level
// Compile time log levels
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON
SPDLOG_TRACE (console, "Enabled only #ifdef SPDLOG_TRACE_ON .. {}, {}", 1, 3.23);
SPDLOG_DEBUG (console, "Enabled only #ifdef SPDLOG_DEBUG_ON .. {}, {}", 1, 3.23);
The following is the output:
Note that the output of trace and debug is not the same. Open spdlog.h and check the definition of SPDLOG_TRACE, you can find that the location of the file ("__FILE__") is also output in the trace.
#ifdef SPDLOG_TRACE_ON
# define SPDLOG_STR_H (x) #x
# define SPDLOG_STR_HELPER (x) SPDLOG_STR_H (x)
# ifdef _MSC_VER
# define SPDLOG_TRACE (logger, ...) logger-> trace ("[" __FILE__ "(" SPDLOG_STR_HELPER (__ LINE__) ")]" __VA_ARGS__)
# else
# define SPDLOG_TRACE (logger, ...) logger-> trace ("[" __FILE__ ":" SPDLOG_STR_HELPER (__ LINE__) "]" __VA_ARGS__)
# endif
#else
# define SPDLOG_TRACE (logger, ...) (void) 0
#endif
#ifdef SPDLOG_DEBUG_ON
# define SPDLOG_DEBUG (logger, ...) logger-> debug (__ VA_ARGS__)
#else
# define SPDLOG_DEBUG (logger, ...) (void) 0
#endif
4. Synchronous and asynchronous settings Asynchronous logging
Official description: https://github.com/gabime/spdlog/wiki/6.-Asynchronous-logging
By default, asynchronous mode is not enabled, and the asynchronous mode is enabled as follows:
size_t q_size = 4096; // queue size must be power of 2
spdlog :: set_async_mode (q_size);
Queue size:
The memory occupied by the queue = the set queue size * the size of the slot, and the slot size in a 64-bit system is 104 bytes. Therefore, the queue size can be determined according to the total log output of the system.
Queue mechanism:
In asynchronous mode, all the output logs will be stored in the queue first, and then the worker thread will take the logs out of the queue and output them. When the queue is full, you need to handle the new log (blocking messages or discarding messages) according to the set queue full strategy. If an exception is thrown in the worker thread, the exception will be thrown again when writing the next log to the queue, and you can catch the worker thread exception when writing to the queue.
When the queue is full (Full queue policy), there are two ways to deal with it:
(1) Block new incoming logs until there is free space in the queue. This is the default treatment.
(2) Discard the new log. as follows:
spdlog :: set_async_mode (q_size, spdlog :: async_overflow_policy :: discard_log_msg)
The two coping methods are as follows:
// Async overflow policy-block by default.
//
enum class async_overflow_policy
{
block_retry, // Block / yield / sleep until message can be enqueued
discard_log_msg // Discard the message it enqueue fails
};
5. Handle spdlog exception set_error_handler
Official description: https://github.com/gabime/spdlog/wiki/Error-handling
When an exception occurs when outputting the log, spdlog will print a statement to std :: err. In order to avoid the screen of the abnormal statement output, the printing frequency is limited to one per minute.
When the following function is executed, since only four parameters are given in the last log output statement, spdlog calls the exception handling function and outputs an exception.
void err_handler_example ()
{
// can be set globaly or per logger (logger-> set_error_handler (..))
spdlog :: set_error_handler ([] (const std :: string & msg)
{
std :: cerr << "my err handler:" << msg << std :: endl;
});
spd :: get ("console")-> info ("some invalid message to trigger an error {} {} {} {}", 3);
}
6. apply_all makes all loggers output simultaneously
All registered loggers will output the sentence End of example, which means the end of the program.
// Apply a function on all registered loggers
spd :: apply_all ([&] (std :: shared_ptr <spdlog :: logger> l)
{
l-> info ("End of example.");
});
7.drop-release logger
At the end of the program, drop_all () should be called to release all loggers.
There is a bug in VS runtime that cause the application dead lock when it exits. If you use async logging, please make sure to call spdlog :: drop_all () before main () exit. If some loggers are not in the registry, those should be released manually as well. stackoverflow: std :: thread join hangs if called after main exits when using vs2012 rc
// Release and close all loggers
spdlog :: drop_all ();
Or drop a logger alone
spd :: drop ("console");
spd :: drop ("basic_logger");
Introduction to c ++ log output library spdlog (2)