Backtrace Logging¶
Backtrace logging enables log messages to be stored in a ring buffer and can be:
Displayed later on demand
Automatically flushed when a high severity log message is logged
To enable backtrace logging, initialize it first with an appropriate log level use LoggerImpl::init_backtrace()
.
By default, backtrace logs are automatically flushed when an error occurs.
To manually flush backtrace logs, call LoggerImpl::flush_backtrace()
.
Note
Backtrace log messages are always pushed to the SPSC (Single Producer Single Consumer) queue from the frontend to the backend. They are stored in a ring buffer that resides in the backend and flushed as needed.
Note
Backtrace log messages store the original timestamp of the message. Since they are stored and flushed later, the timestamps in the log file may appear out of order.
Store messages in the ring buffer and display them when LOG_ERROR
is logged¶
1#include "quill/Backend.h"
2#include "quill/Frontend.h"
3#include "quill/LogMacros.h"
4#include "quill/Logger.h"
5#include "quill/sinks/ConsoleSink.h"
6
7int main()
8{
9 quill::Backend::start();
10
11 quill::Logger* logger_1 = quill::Frontend::create_or_get_logger(
12 "logger_1", quill::Frontend::create_or_get_sink<quill::ConsoleSink>("sink_id_1"));
13
14 quill::Logger* logger_2 = quill::Frontend::create_or_get_logger(
15 "logger_2", quill::Frontend::create_or_get_sink<quill::ConsoleSink>("sink_id_1"));
16
17 // a LOG_ERROR(...) or higher severity log message occurs via this logger.
18 // Enable the backtrace with a max ring buffer size of 2 messages which will get flushed when
19 // Backtrace has to be enabled only once in the beginning before calling LOG_BACKTRACE(...) for the first time.
20 logger_1->init_backtrace(2, quill::LogLevel::Error);
21
22 LOG_INFO(logger_1, "BEFORE backtrace Example {}", 1);
23
24 LOG_BACKTRACE(logger_1, "Backtrace log {}", 1);
25 LOG_BACKTRACE(logger_1, "Backtrace log {}", 2);
26 LOG_BACKTRACE(logger_1, "Backtrace log {}", 3);
27 LOG_BACKTRACE(logger_1, "Backtrace log {}", 4);
28
29 // Backtrace is not flushed yet as we requested to flush on errors
30 LOG_INFO(logger_1, "AFTER backtrace Example {}", 1);
31
32 // log message with severity error - This will also flush_sink the backtrace which has 2 messages
33 LOG_ERROR(logger_1, "An error has happened, Backtrace is also flushed.");
34
35 // The backtrace is flushed again after LOG_ERROR but in this case it is empty
36 LOG_ERROR(logger_1, "An second error has happened, but backtrace is now empty.");
37
38 // Log more backtrace messages
39 LOG_BACKTRACE(logger_1, "Another Backtrace log {}", 1);
40 LOG_BACKTRACE(logger_1, "Another Backtrace log {}", 2);
41
42 // Nothing is logged at the moment
43 LOG_INFO(logger_1, "Another log info");
44
45 // Still nothing logged - the error message is on a different logger object
46 LOG_CRITICAL(logger_2, "A critical error from different logger.");
47
48 // The new backtrace is flushed again due to LOG_CRITICAL
49 LOG_CRITICAL(logger_1, "A critical error from the logger we had a backtrace.");
50}
Store messages in the ring buffer and display them on demand¶
1#include "quill/Backend.h"
2#include "quill/Frontend.h"
3#include "quill/LogMacros.h"
4#include "quill/Logger.h"
5#include "quill/sinks/ConsoleSink.h"
6
7int main()
8{
9 quill::Backend::start();
10
11 quill::Logger* logger = quill::Frontend::create_or_get_logger(
12 "logger", quill::Frontend::create_or_get_sink<quill::ConsoleSink>("sink_id_1"));
13
14 // Store maximum of two log messages. By default, they will never be flushed since no LogLevel severity is specified
15 logger->init_backtrace(2);
16
17 LOG_INFO(logger, "BEFORE backtrace Example {}", 2);
18
19 LOG_BACKTRACE(logger, "Backtrace log {}", 100);
20 LOG_BACKTRACE(logger, "Backtrace log {}", 200);
21 LOG_BACKTRACE(logger, "Backtrace log {}", 300);
22
23 LOG_INFO(logger, "AFTER backtrace Example {}", 2);
24
25 // flush the backtrace manually
26 logger->flush_backtrace();
27}