Pull to refresh

Comments 42

Какие из этих логгеров поддерживают логгирование структурированной информации?

Сайт P7 уронили хабраэффектом :(
Жалко, было бы интересно посмотреть
А можно ссылочку на конкретные настройки для каждого логгера в ваших тестах?
Как раз стояла цель не заниматся кастомизацией, а взять и использовать, так что кроме теста производительности в условиях равного потребления памяти никаких спец настроек не применялось. Все по умолчанию.
Не, ну это ни о чем. То-то я смотрю по вашим тестам асинхронный g3log наравне с синхронными логгерами. Там flush policy по умолчанию = 1.
Я думаю, в большинстве проектов не занимаются тонкой настройкой логера из-за времени/сроков/лени :-)

А знает ли кто-нибудь вменяемую библиотеку фасада логгирования? Т.е. уже написанные функции вывода сообщения, пачка макроссов и т.п. Потому как писать каждый раз велосипед на эту тему немного раздражает.

Boost.Log, всё-таки, очень хотелось бы увидеть в сравнении.
Это достаточно хорошая библиотека в плане функционала, постараюсь выкроить время и добавить ее в сравнение
Статья обновлена, Boost добавлен
А почему boost не рассмотрен? Просто любопытно.
Время, эта статья заняла несколько недель моей жизни, в принципе вижу, что интерес к бусту есть, постараюсь найти время и обновить статью.
Статья обновлена, Boost добавлен
Спасибо за статью, как раз сейчас думаю какой логгер использовать. А что вы знаете/думаете насчет Boost.Log?
Хорошая библиотека в плане функционала, немного тяжеловата в плане скорости, но повторюсь — ее главный плюс функционал.
Спасибо, скорость в моем нынешнем проекте не так важна. Буду использовать Boost.
Статья обновлена, Boost добавлен
Думаю стоит отметить, что spdlog использует для вывода библиотеку fmt, и, на данный момент, не поддерживает стандартные printf последовательности. Не знаю плюс это или минус, но внимание обратить стоит.

Пользовался Easylogging и spdlog, удобно настраиваются, но компиляция ~5 секунд на простом hello world очень расстраивает, ох уж эти темплейты.
Спасибо за комментарий, статья поправлена. Скорее это минус ибо препятствует безболезненной замене одного логера другим, нужно будет выпиливать все руками и тестировать каждый вызов лог функции.
Понравился хороший анализ внутренностей.
Но не нравится постанова вопроса: какая библиотека лучше. И вот почему: выбор «логера» зависит еще (а на мой взгляд в первую очередь) от того, что вы хотите достичь.
1. Я имею ввиду следующее: лог трассировки это одно — для дебага вполне может подойти те библиотеки о которых вы говорите. Но допустим для аудита (лога безопасности)-нет. Они не ответят быстро на вопрос, а кто имел доступ к определенному объекту (например, запись о клиенте созданная 10 лет назад и редактируемая время от времени), и кто его и почему изменял — для этого лучше, чтобы лог был не в виде «плоского файла» с кучей другого мусора, а в виде структутрированной и нормализированной БД — вряд ли указанные логгеры позволяют делать что-то подобное.
2. А еще событие в трассировочном файле (для программиста, например событие с уровнем Warning) может иметь совершенной другой смысл (и уровень) для администратора (от вообще ничего не значащего, до Error). Аналогично относительно самого сообщения. Для программиста нужно выводить стек ошибки, для администратора — вряд ли. Ему бы лучше описание проблемы и решения.
3. Еще логгеры навязывают свою классификацию уровня сообщений. Мне часто не хватает уровня Success и Fail(типа Info, но с другим «оттенком» — так по логу проще искать удачные и не удачные операции), не хватает дополнительной категоризации — кроме уровня и категории, например название операции; или уникальный номер операции (номер потока не подходит) — приходится придумывать
А вообще это я к чему… На мой взгляд правильнее:
* для себя и команды выработать правила как, что и когда логгировать (я имею ввиду трассировку) и как обрабатывать эти логи
* отталкиваться от требований (какие еще логи нужно вести — для админов, для безопасников...) в каждом конкретном проекте — от этого может поменяться и подход вообще.
* выработать для себя интерфейс с набором удобных методов логгирования
* а потом под этой интерфейс реализовывать что угодно и иметь возможность в любой момент поменять библиотеку на любую другую.
Вы правы, для каждой задачи свой инструмент и если я правильно понял автора — сравниваются логеры по различным критериям и как раз была попытка уйти от формата советов «я пользуюсь бустом и мне хорошо», а дать более объективную картину, а каждый уж пусть решает для себя сам в зависимости от поставленной задачи.
Не знаю как у log4cpp, а вот у его «идейного предка» log4cxx на 30 минут работы написать свои аппендеры, например dailyrolling. Да и ещё через час работы над его словами его можно спокойно заставить миксовать wchar_t* и обычный char* (правда с условием, что первым будет wchar_t логгироваться) в одной строчке. Так же log4cxx не имеет таких минусов log4cpp как ограничение на 1024 символов в строке (хоть мегабайты туда пиши) и на исключение при отсутствие файла с логами (реально такое было лет 9 назад в версии 0.9.х). И ещё плюс — это динамическая конфигурация логгера (не перезапуская программу), он умеет следить за конфигурационный файлом и на лету подхватывать из него новые настройки. Так же странно, что синхронность отнесена к недостаткам. Обычно наоборот в случае падения приложения самые интересные логи они в самом конце. А если они не успеют сброситься на диск, то беда беда.
Так же у обоих большой плюс в том что для этого семейства логгеров (включая log4j и log4net) есть сторонние инструменты для работы с файлами логов, не надо придумывать свои велосипеды (например, logMX).
на 30 минут работы написать свои аппендеры

Задача статьи сравнить логеры с точки зрения их простоты использования. Возможно для Вас это 30 минут работы, для другого инженера не знакомого с логером — это несколько дней плюс тестирование и исправления и все это при наличии желания, особенно если можно взять что-то другое где функция доступна из коробки.

Так же странно, что синхронность отнесена к недостаткам

Я не смог отнести к достоинствам тот факт, что синхронный логер может приостановить выполнение вашей программы на длительное время только потому, что обращается к файлу, а HDD скажем занят. Для домашних проектов это не ограничение, для серьезных проектов — лучше не иметь таких случайных задержек плюс существенное падение производительности в случае интенсивного логирования.

Обычно наоборот в случае падения приложения самые интересные логи они в самом конце. А если они не успеют сброситься на диск, то беда беда

Перехват падений в этом случае решает проблему, можно даже стэк распечатать или сохранить краш дамп — самый простой способ найти и исправить дефект в разумные сроки.

logMX

Утилита стоит денег если используется профессионально.
Задача статьи сравнить логеры с точки зрения их простоты использования. Возможно для Вас это 30 минут работы, для другого инженера не знакомого с логером — это несколько дней плюс тестирование и исправления и все это при наличии желания, особенно если можно взять что-то другое где функция доступна из коробки.

Смысл моего этого замечания на самом деле был в том, что log4cxx (уверен, что это относится и к log4cpp/log4cplusplus) можно быть сильно, и быстро, кастомизировать под свои кейзы в случае необходимости. Конечно, такое требуется обычно раз в жизни, но обычно в тот самый момент, когда времени переходить на новый логгер точно не будет. Я, кстати, слабо представляю зачем тот же DayliRollingAppender вообще нужен, хоть и делал его. Другими словами, кастомизация логгера — это один из кейсов его использования. И если вы хотели «сравнить логеры с точки зрения их простоты использования», простота расширения log4cxx — это вообще в тему.

Я не смог отнести к достоинствам тот факт, что синхронный логер может приостановить выполнение вашей программы на длительное время только потому, что обращается к файлу, а HDD скажем занят. Для домашних проектов это не ограничение, для серьезных проектов — лучше не иметь таких случайных задержек плюс существенное падение производительности в случае интенсивного логирования.

Это большой миф, что синхронное логгирование может что-то там замедлить. Объясню на примере. Мы делаем софт, который сильно грузит cpu и диск. И для нас каждый процент cpu, так же как любая задержка работы с файловой системой, очень важен. Вплоть до того, что пришлось Sleep(0.5) реализовывать, так как 1 миллисекунда для нас — это слишком большая задержка. Соответственно, постоянно профилируемся по нагрузке проца, и часто ищем задержки с помощью gpuview и других тулзовин. Так вот, синхронный логгер не даёт ни сколько нибудь значительную нагрузку на cpu, ни сколько нибудь значительных задержек работы с файловой системой. Насколько я помню, несмотрю на то, что пишет он синхронно в файл, то сам файл по дефолту флашится на диск сразу после записи только при ERROR/FATAL. А так собственно есть буферизация в винде, по умолчанию винда скидывает данные на диск большими блоками (аля секторами), что очень эффективно. В синтетических тестах может и есть какая-то разница с асинхронными логгерами, а вот в реальных приложениях — нету.

Перехват падений в этом случае решает проблему, можно даже стэк распечатать или сохранить краш дамп — самый простой способ найти и исправить дефект в разумные сроки.

Вы зря путаете логгирование и перехват исключений. Одно другое никак не заменяет. А случаев, когда партнёр, находясь в 300 км от ближайшего интернета, по телефону зачитывает логи модуля, который падает, за неимением возможности выслать даже минимальные дампы, в моей практике было не один, не пять, и даже не 10. Кстати, как показала практика — распечатывание стека при падении в самом падающем приложении — тоже не состоятельная идея (применительно к Винде). Там куча проблем, которые надо решать. Например, либо символы в бинари встраивать (C7), увеличивая их размер в разы, а то и в десятки раз, либо всё-таки старая добрая pdb и раскрутка стека на машине разработчика. Или ещё например, что бы записать в файл, когда закончилась память (выжрали 4 гига, и new постоянно кидает bad_alloc), тоже надо постараться, так как даже fopen пытаться выделить некие буффера, и если памяти реально не осталось, то даже это сделать не получится, и том чтобы использовать ofstream разговор вообще уже не идёт (если что я знаю как такую проблему решать, я к тому, что это всё не тривиально).

Утилита стоит денег если используется профессионально.

Вы здесь опять суть не уловили. Дело не в том, что есть бесплатный logmx для некоммерческого использования, а в том, что для log4j/log4net/log4cxx построена огромная инфрастуктура. Тех же анализаторов логов можно за 10 минут наверное с десяток нагуглить, на любой вкус и кошелёк, всё не закачанчивается на logmx'е. Кстати, обычные логи в log4cxx настраиваются так хорошо, что обычно не требуют специализированных средств для своего анализа, обычно это бывает полезно в очень специфичных случаях.
Кстати, за саму статью и за тот огромный труд, что вы проделали, большое вам спасибо!

Мой комментарий не принимайте близко к себе. Просто меня немного задело «ограничение на 1024 символов в строке и на исключение при отсутствие файла с логами». Решил рассказать людям, о его старом дедушке — рабочей лошадке log4cxx, лишённого этих детских болезней.
Спасибо, я не принимаю на свой счет, вижу, что у Вас богатый опыт, Вы приводите свои примеры из практики, не сомневаюсь, что для ваших случаев эти утверждения были истины.
Смысл моего этого замечания на самом деле был в том, что log4cxx

Опыт показывает, что при наличии опыта и мотивации можно кастомизировать почти все :) Вопрос чаще всего стоит во времени. Но вы правы эти логеры не так сложны в кастомизации при наличии опыта.
Это большой миф, что синхронное логгирование может что-то там замедлить.

Видимо зависит от области, устройств и тд, так как если вы пишете только ошибки и время от времени распечатываете какие то значения то никакого вреда от синхронного логгера не будет. Если речь идет о тысячах в секунду то уже приходится считать.
На прошлой работе люди писали по 30-40 тысяч сообщений в секунду в нормальном режиме и порядка 2.5M под нагрузкой (разработка железа и софта к нему), синхронный логгер такого просто не вытянет, физически. Если у вас маленькое линукс устройство и нужно логировать каждый чих — тоже нет смысла даже пытаться прикрутить синхронный логер, процессор будет обслуживать только его.
Пересчет одного лог вызова в наносекунды дело бессмысленное если у вас 3 лог строчки в секунду и очень полезное если вы занимаетесь трассированием.
Я что пытаюсь сказать — зависит от области где вы применяете и самое главное как.
Вы зря путаете логгирование и перехват исключений. Одно другое никак не заменяет.

Хотел лишь сказать, что они друг друга очень неплохо дополняют и сброс важных буферов в случае краша дело полнезное, будь то синхронный логер пишущий в свой внутренний буфер и сбрасывающий время от времени в файл или асихнронный.
А уж краш дамп если он есть — даст фору логу и приличную в плане «поймать и убить».
Распечатывание стека при падении в самом падающем приложении

Согласен, под виндой страшный ужас, под Линуксом — достаточно легко.
Тех же анализаторов логов можно за 10 минут наверное с десяток нагуглить

Да, вы правы, софта такого рода много, да и самому его сделать не сложно.

Еще раз спасибо за отзыв и комментарии и поменьше Вам случае зачитывания логов по телефону :) А логеры… зависит от области, знаний, способов применения, наличия сети и кучи других факторов, в любом случае никого не хотел обидеть, а только дать некий срез по десяткам критериев.
насколько я помню у log4cpp есть сетевой адаптер, который передаёт данные по не своему протоколу.
У меня есть свой логгер, основу которого я заложил ещё в далёком 2004 году. И с тех пор ещё никогда такого не было, чтобы мне удалось использовать его в каком-то проекте без изменений. Каждый раз приходится либо что-то допиливать в самом логгере под конкретный проект, либо отказываться от его использования вообще. Так что я давно на собственном опыте понял, что «законченная библиотека логирования» — это оксюморон. Ну, или что-то типа единорога. Можно очень легко представить его мысленно, поскольку существует обширная мифология на эту тему. Но похоже, что в реальности ничего такого нет.
Статья большая и основательная, автору большое спасибо за проделанную работу!

Но пока читал, прям на фразу «если какой-то очень важный логгер был пропущен (boost к примеру)» очень расстроился. Мне кажется, для многих проектов Boost.Log является стандартом де-факто логгирования, ведь все равно часто boost приходится тащить с собой. Собственно, у себя его и используем, как вы сказали, «полет нормальный».
Да. Именно потому, что Boost все равно уже прикручен я и решил на нем остановиться. Грустно только, что даже tutorials с официального сайта не работают без приседаний.
Статья обновлена, Boost добавлен

Вы не знаете, есть какой-то способ единообразно генерировать Precompiled-Headers для clang и gcc?
Что бы в Makefile можно было просто заменить CPP = g++ на CPP = clang++?

Знаю. Используйте cmake, который вам сгенерирует Makefile для нужного компилятора, и вот эту примочку к нему, которая умеет проставлять cmake'у правильные флаги прекомпилированных заголовков, и для clang, и для gcc, и даже для visual studio.
Вы правы — это снизит время компиляции.
В статье я постарался рассказать о том какие особенности у каждого логера и какие дополнительные действия нужно предпринять чтоб интеграция и использование принесли желаемую пользу.
А можно log4cplus добавить?
Хорошая лицензия. Разработка не заморожена.
Сейчас на очереди Boost.Log, как его закончу постараюсь найти время и посмотреть в сторону предложенного вами проекта.
Изучение каждого логера занимает существенное время, Boost например занял чуть больше недели и еще не закончен.
Если я не ошибаюсь Вы являетесь одним из контрибьюторов этого проекта — если это так и вы готовы помочь мне с ответами на некоторые вопросы связанные с предложенным вами логером (что существенно сократит время на вычитку документации и исходников) — пожалуйста скиньте в личку контактный е-мэйл.
Всего наилучшего!
По поводу P7:

+ Высокая производительность + высокая точность временных меток, большой отрыв от ближайшего конкурента SpdLog

— Высоко интенсивное использование логера из нескольких потоков снижает (в 2.3 раза) производительность логера (плата за последовательность лог сообщений и временных меток)

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

Запустил ваш тест на нашем рабочем логгере (который на 100% написан мной :)


Kонфигурация:


  • Window 7x64 (6.1.7601 Service Pack 1 Build 7601)
  • Visual studio 2015, update 3
  • RAM: 16Gb (???)
  • CPU: Intel Core i7-3770 @ 3.40GHz (~ +40%)
  • HDD: SanDisk SDSSDHP256G ATA Device

Строка в коде выглядит так:


LOGF_TRC("Message + all required information, #%u", i);


в файле:


[07968] [2016/12/22 15:56:22.625] [TRC] main(): Message + all required information, #0


Releаse Time (ms):
1 поток в синхронном режиме — 3300
1 поток в асинхронном режиме — 200
4 потока в синхронном режиме — 4800
4 потока в асинхронном режиме — 150

Должен снять шляпу перед автором данной статьи. Все benchmarkи которые я на данный момент находил проводили тестирование на single и multithreading, а все остальное — тоже важная информация упускалась.

Мне интересно было бы ещё посмотреть есть ли на какой код code coverage и сколько он процентов, а также интересен сам benchmark тест — на тот случай, если захочу сделать свой собественный логгер. Возможно ли выложить сами тесты куда-нибуть — скажем на github.

Можно было бы заодно посмотреть код и побегать по нему.
Sign up to leave a comment.

Articles