Site icon Заметки разработчика

Каналы в библиотеках логирования C++

Каналы в библиотеках логирования C++ spdlog и logme

Поддержка каналов в библиотеках логирования — важная тема для C++-проектов, где необходимо разделять, фильтровать и маршрутизировать сообщения разных подсистем. Поддержка каналов в библиотеках логирования напрямую влияет на удобство анализа логов и гибкость системы.


Зачем нужна поддержка каналов в библиотеках логирования

Поддержка каналов в библиотеках логирования позволяет логически разделять сообщения разных частей системы.

В достаточно сложных проектах почти всегда есть несколько подсистем, сообщения от которых удобно собирать отдельно. Например, если проект представляет собой web-сервер, логично:

Только в таком случае данные остаются структурированными и удобными для анализа.


Поддержка каналов в библиотеках логирования: подходы

Разные библиотеки реализуют поддержку каналов в библиотеках логирования по-разному. Рассмотрим два популярных подхода на примере spdlog и logme.

Подробнее о spdlog: https://github.com/gabime/spdlog
Репозиторий logme: https://github.com/efmsoft/logme


spdlog

В spdlog отдельный канал фактически соответствует отдельному logger.
То есть поддержка каналов реализована через создание независимых логгеров с разными sink’ами.

 
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»);
 

Такой подход:


logme

В logme поддержка каналов в библиотеках логирования реализована как отдельная сущность.

Канал создаётся явно, после чего к нему подключаются бекенды:

 
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»);
 

Поддержка каналов в библиотеках логирования в этом случае становится более гибкой:


Дополнительные возможности каналов в logme

Поддержка каналов в библиотеках логирования в logme включает дополнительные механизмы, которые отсутствуют в базовой модели spdlog.


Отключение логирования на этапе компиляции

Вывод выполняется через макросы (LogmeI, LogmeD), что позволяет:

Это важное преимущество, так как вызовы методов (logger->info(...)) остаются в коде даже при отключённом уровне.


Связывание каналов (маршрутизация)

Каналы можно связывать:

 
log1->AddLink(log2);
 

После этого все сообщения из log1 автоматически дублируются в log2.

Поддержка каналов в библиотеках логирования в таком виде позволяет:


Управление маршрутизацией для отдельных сообщений

Можно управлять поведением для конкретного сообщения:

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

LogmeI(log1, ovr, «message only for log1»);
 

В этом случае сообщение:


Ключевые различия

Если обобщить поддержку каналов в библиотеках логирования:

spdlog

logme


Итог

Поддержка каналов в библиотеках логирования реализуется по-разному и определяет возможности системы.

Если в проекте важно:

то поддержка каналов в библиотеках логирования становится ключевым фактором выбора.

Exit mobile version