Site icon Developer's tips

Logging channels in C++: spdlog vs logme

Support for channels in logging libraries: spdlog vs logme architecture and routing

Support for channels in logging libraries is an important topic for C++ projects where it is necessary to separate, filter, and route messages from different subsystems. Support for channels in logging libraries directly affects how easy it is to analyze logs and how flexible the system is.


Why support for channels in logging libraries matters

Support for channels in logging libraries allows you to logically separate messages coming from different parts of the system.

In sufficiently complex projects, there are always multiple subsystems whose logs should be handled independently. For example, in a web server it is common to:

Only with this approach do logs remain structured and easy to analyze.


Support for channels in logging libraries: approaches

Different libraries implement support for channels in logging libraries in different ways. Let’s look at two popular approaches using spdlog and logme.

More about spdlog: https://github.com/gabime/spdlog
Logme repository: https://github.com/efmsoft/logme


spdlog

In spdlog, a channel effectively corresponds to a separate logger.
In other words, support for channels in logging libraries is implemented via multiple loggers with different sinks.

 
auto sink1 = std::make_shared<spdlog::sinks::basic_file_sink_mt>("log1.txt", true);
auto logger1 = std::make_shared<spdlog::logger>("log1", sink1);

auto sink2 = std::make_shared<spdlog::sinks::basic_file_sink_mt>("log2.txt", true);
auto logger2 = std::make_shared<spdlog::logger>("log2", sink2);

logger1->info("Message for log1");
logger2->info("Message for log2");
 

This approach:


logme

In logme, support for channels in logging libraries is implemented as a first-class concept.

A channel is created explicitly, and backends are attached to it:

 
auto log1 = Logme::Instance->CreateChannel();
auto file1 = std::make_shared<Logme::FileBackend>(log1);
file1->CreateLog("log1.log");
log1->AddBackend(file1);

auto log2 = Logme::Instance->CreateChannel();
auto file2 = std::make_shared<Logme::FileBackend>(log2);
file2->CreateLog("log2.log");
log2->AddBackend(file2);

LogmeI(log1, "Message for log1");
LogmeI(log2, "Message for log2");
 

Support for channels in logging libraries in this model becomes more flexible:


Additional channel features in logme

Support for channels in logging libraries in logme includes several advanced capabilities that go beyond the basic spdlog model.


Compile-time disabling of logging

Logging is done via macros (LogmeI, LogmeD), which allows you to:

This is a key difference compared to method calls (logger->info(...)), which remain in the binary even when disabled.


Channel linking (routing)

Channels can be linked:

 
log1->AddLink(log2);
 

After that:

Support for channels in logging libraries in this form allows you to:


Per-message routing control

You can override routing for specific messages:

 
Logme::Override ovr;
ovr.Add.DisableLink = true;

LogmeI(log1, ovr, "message only for log1");
 

In this case:


Key differences

If we summarize support for channels in logging libraries:

spdlog

logme


Conclusion

Support for channels in logging libraries is implemented differently and directly affects system capabilities.

If your project requires:

then support for channels in logging libraries becomes a key factor in choosing a logging solution.

Exit mobile version