-
Notifications
You must be signed in to change notification settings - Fork 0
2. Creating loggers
Each logger contains a vector of one or more std::shared_ptr<spdlog::sink>
.
On each log call (if the log level is right) the logger will call the sink(log_msg)
function on each of them.
spdlog's sinks have _mt (multi threaded) or _st (single threaded) suffixes to indicate the thread safety. While single threaded sinks cannot be used from multiple threads simultaneously they might be faster because no locking is employed.
The easiest way to create loggers is to use the factory functions in spdlog.h:
//Create and return a shared_ptr to a multithreaded console logger.
auto console = spd::stdout_logger_mt("some_unique_name");
This will create a console logger, register it in spdlog's global registry with "some_unique_name" as its id, and return it as shared_ptr.
Loggers can be accessed from anywhere using the thread safe spdlog::get("logger_name")
which returns a shared pointer.
Note: spdlog::get
might slow your code down since it locks a mutex, so use with caution. It is advisable to save the shared_ptr<spdlog::logger>
returned and use it directly, at least in code hot paths.
A good approach would be to have a private member of type shared_ptr<spdlog::logger>
which will be set in the constructor:
class MyClass
{
private:
std::shared_ptr<spdlog::logger> _logger;
public:
MyClass()
{
//set _logger to some existing logger
_logger = spdlog::get("some_logger");
//or create directly
//_logger = spdlog::rotating_file_logger_mt("my_logger", ...);
}
};
Note 2: Manually created loggers (i.e. those not created using the <spdlog.h>
factory methods) do not get automatically registered and will not be found by the get("...")
call.
If you want to register such logger use the register_logger(...)
function:
spdlog::register_logger(my_logger);
...
auto the_same_logger = spdlog::get("mylogger");
//Create rotating file multithreaded logger
auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);
...
auto same_logger= spdlog::get("file_logger);
Calling the spdlog::set_async_mode(size_t queue_size, const async_overflow_policy)
instructs spdlog to create asynchronous loggers.
The queue_size
parameter establishes the fixed number of pre-allocated slots in the message queue and must be a power of two.
When trying to log a message and the queue is full, what happens next is dictated by the async_overflow_policy
parameter - block until a slot becomes available (default), or discard the message.
//Create an asynchronous rotating file multi threaded logger
spdlog::set_async_mode(1048576);
auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);
auto sink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
auto my_logger= std::make_shared<spdlog::logger>("mylogger", sink);
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_st>());
sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_st>("logfile", "txt", 23, 59));
auto combined_logger = std::make_shared<spdlog::logger>("name", begin(sinks), end(sinks));
//register it if you need to access it globally
spdlog::register_logger(combined_logger);
If you want to have different loggers to write to the same output file all of them must share the same sink. Otherwise you might get strange results.
auto sharedFileSink = std::make_shared<spdlog::sinks::simple_file_sink_mt>("fileName.txt");
auto firstLogger = std::make_shared<spdlog::logger>("firstLoggerName", sharedFileSink);
auto secondLogger = std::make_shared<spdlog::logger>("secondLoggerName", sharedFileSink);