Идеальное логирование в .NET приложении. Как достичь? Что использовать?
Какая задача: хочу писать логи так, чтобы можно потом было их удобно читать, фильтровать, выкидывать из них лишнее. Простой пример, есть класс, который по таймеру что-то проверяет 1 раз в секунду и 1 раз в секунду пишет что-то в логи. Всё это активируется, если в приложении перейти на определённую страницу (навигация в UWP приложении), на которую не так уж и редко переходят. Когда смотришь такие логи - это боль, так как там ещё логирование всех HTTP запросов и ответов. В них очень сложно увидеть картину, если ищешь причину возникновения ошибки. Например, я хочу в логах увидеть, что происходило с момента запуска приложения, а именно переходы по страницам, и что происходило на последней странице только внутри определённых сервисов (видеть логи только этих сервисов).
Я убеждён, что логи должны быть не в виде обычных строк, а писаться в виде каких-нибудь структур данных, например, в БД SQLite. Наверняка придётся написать своё приложение, которое извлекает только нужное из БД с фильтрами. Может быть что-то готовое уже есть или есть какие-то идеи, советы?
Механизм таков:
1. Везде где есть логи пишем в стандартный логгер из Microsoft.Extensions.Logging, там ILogger, где T - тип класса, из которого пишем логи.
2. Поднимаем ELK стэк рядом или на соседней машине
3. В конфигурации приложения подключаем реализацию логгера, умеющую отправлять логи в Logstash (например Serilog)
4. Не забываем в конфигурации приложения сделать fallback - если в Logstash не получилось, кидаем в файл (потом если что можно руками скормить)
5. Если нужно, фильтруем логи на уровне Logstash (как минимум нужно предусмотреть, чтобы логи шли в нужный индекс в ElastickSearch)
6. Настраиваем дашборды в Kibana и мониторим работу приложения.
P.S. может это конечно из пушки по воробьям, но как вариант можно использовать часть ELK стэка если все не нужно - тот же логстеш может не в эластик писать, а в файл насколько я помню - т.е. можно сделать наборы файлов по фильтрам.
ёлка, правда во-первых подразумевает поболее одного эластика, да и логсташей, ну и с января этого года там нюансы с лицензиями...
p.s. класс логгеров можно расширить до бесконечности, если между логгером в файлы и ёлкой задействовать filebeat
p.p.s. почти все распространенные логгеры как правило умеют из коробки или же там все готово для допиливания до "хранение логов в БД" (ну чтобы уйти от монстров типа ёлки в рамках pet-проектов)
Насчет конкретных библиотек сказать не могу, т. к. пользуюсь самописной, но elastic stack позволяет анализировать и визуализировать логи на лету.
Также несколько советов логирования:
1) разделите вашу программу на логические многоуровневые вложенные подсистемы, т. е. при логировании, например, кнопки к сообщению добавляется аттрибут system=client.ui.form
2) приоритезируйте логи, т. е. при ошибке добавляется аттрибут level=error, при вылете =critical, при отладке =trace...
3) добавьте другие полезные аттрибуты для анализа, например дату и время, id пользователя
4) используйте двустороннюю человеко-читаемую сериализацию, т.е. не тупо текст, а какой-нибудь csv или json (обязательно utf8)
5) используйте базу данных или ротацию по времени и размеру
6) централизуйте хранение и анализ логов
7) используйте препроцессор для логирования отладки только в отладочной сборке, а лучше используйте нормальный отладчик с отслеживанием событий и условной остановкой
P. S.
Главное правило логирования: воспроизвести проблему на машине разработчика, а не задокументировать ее на машине пользователя.
Берем логгер который умеет структурное логгирование: Microsoft.Extensions.Logging или Serilog.
Берем базу данных которая умеет хранить документы.
Есть несколько опций:
- Seq (бесплатен для разработки, но для бизнеса платный)
- ApplicationInsights (нужет Azure, есть мизерный бесплатный лимит логов на день, дальше платно)
- ElasticSearch + Kibana
- Grafana + Loki
Есть, конечно, и другие БД для хранения доков, но то что я указал, ближе всего к задаче