Как стать автором
Обновить

Комментарии 37

Почему нет Microsoft.Extensions.Logging, который сейчас стандарт де-факто для Core?
Вы пишете про Serilog, но при этом ни словом не упоминаете про структурное логирование?


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

А зачем для логирования многопоточных приложений какая-то "асинхронная обертка"?

Как вариант - писать логи в сеть, а сеть медленная.

Как вариант — писать логи в сеть, а сеть медленная.

При чем тут многопоточное приложение?


Это типовая проблема быстрого генератора логов, и она решается конкретным приемником логов, т.е. тот приемник логов, который пишет в сеть, сам внутри себя решает, как ему бороться с тем, что сеть медленная.


Ну а если кому-то вдруг надо сделать синхронный приемник асинхронным насильно, то у серилога такая обертка тоже есть: https://github.com/serilog/serilog-sinks-async

Нет, не решается. Частично да, но не полностью.

В случах с асинхронным приёмником есть шанс потерять важный лог по какому-то действию, если действие произошло, а потом сервис упал.

А чем отличается упомянутая автором "асинхронная обертка"?

Очень надеюсь, что своей синхронностью, если вы понимаете о чем я.

Нет, не понимаю.


Речь вообще о какой обертке идет? Вот об этой?

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

Так что же, по-вашему, делает упомянутая автором "асинхронная обертка"?


И что же надо делать?

Решает/решать вышеуказанные проблемы.

Ну, обертка по ссылке, которую я привел, делает именно что буфер в фоновом потоке. Вы знаете про какую-то другую "асинхронную обертку" для NLog?


Решает/решать вышеуказанные проблемы.

Как конкретно?

проблема быстрого генератора логов, и она решается конкретным приемником логов, т.е. тот приемник логов, который пишет в сеть, сам внутри себя решает, как ему бороться с тем, что сеть медленная.

Есть классический прием переложить проблему обратно на генератор: "диктуете помедленнее, я.. ик.. записываю" :)

Для логирования это не всегда подходит.

Ну the 12 factor app уже давно сказали, глядя все эти наши попытки родить серебряную пулю: вы все равно не сделаете как надо, поэтому универсальный совет - пишите все в stdout.

Но да и это тоже не всегда работает - иженерные решения в любом случае чем-то ограничены.

Вот именно потому, что это "не всегда работает" (а в моих конкретных сценариях чаще не работает, чем работает), я и не вижу смысла ограничивать себя (неудобной) консолью.

Stdout это не всегда консоль. Даже чаще это не консоль. Но не суть.

И именно поэтому он еще более неудобен, чем консоль. Так что не вижу смысла (повторюсь, в моих применениях).

Я помню, что вы кажется как-то писали про ацкий хайлоад, где нужны специальные решения.

Мне кажется, вы меня с кем-то путаете. Все намного тривиальнее: хосты, где либо stdout нет (типа IIS), либо stdout обрабатывается хуже, чем нативный логгер (типа AWS Lambda).

Простите, это моя ошибка.

Если вы имели ввиду логер из Amazon.Lambda.Core, то он как раз использует Console.WriteLine(), иными словами все тот же stdout.

А вы там видите, да, что этот делегат заменяем? Комментарий не зря написан:


When used outside of a Lambda environment, logs are written to Console.Out.

При этом скажем, их же имплементация для Microsoft.Extensions.Logging то ли использовала, то ли до сих пор использует именно Console.Out, и из-за этого вывод, если он многострочный, в CloudWatch попадает в разбивке. А через нативный логгер, который передается в контексте — нормально всё.

Нам нужно было найти подходящую библиотеку для разных версий framework, начиная с 3.5 и выше. Как я понял, Microsoft.Extensions.Logging поддерживает .Net framework начиная с версии 4.5.

С Serilog вышел косяк насчет структурного логирования. Не добавил блок с ним.

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

Нам нужно было найти подходящую библиотеку для разных версий framework, начиная с 3.5 и выше.

Ну так с этого и надо начинать: "описание библиотек логирования, совместимых с .net 3.5". Далеко не всем в 2022 это интересно.


И да, какая версия Serilog поддерживает 3.5?


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

А без нее что происходило?

Я знаю, что тут бывает две проблемы. Условно М и Ж (евпочя). Могу предложить, что потоки либо пытались писать в файл одновременно всей бандой, и там все так и получалось - вперемешку, что не поддается ни какому анализу. Либо делали общий лок на запись, - чтобы одномоментно мог писать только один, а остальные ждали - и потом в равной степени все об него запинались. "Асинхронная обёртка", прекратила эту демократию, втихоря назначив файлу отдельного хозяина, а генераторов заставила приносить к нему свои логи дискретно, в баночках.

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

Это кривая имплементация файлового приемника, если он такое позволяет. Серилоговский, скажем, просто не позволяет, там во сколько потоков не пиши в один приемник, записи будут целостными.


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

А это снова вырождается в проблему "мы производим логи быстрее, чем пишем" (которая прекрасно существует в однопоточных приложениях тоже), и для ее решения у серилога-таки есть два разных враппера.


Я это к тому, что выглядит так, что автор поста выбрал NLog вместо Serilog не потому, что второй что-то не умеет, а потому, что у второго философия "батарейки отдельно" (и эту философию автор Serilog, кстати, явно озвучивает). Нужно вам чтение из конфига? Вот пакет. Нужен вам асинхронный враппер? Вот пакет. Не нужно ни то, ни другое? Вы не тащите эти зависимости с приложениям.

Серилоговский

У меня была другая метафора. Но так даже ещё смешнее :)

Не очень понимаю, при чем тут какая-то метафора. Serilog — это название пакета.

"there's two hard problems in computer science: we only have one joke and it's not funny."

И нет старого доброго System.Diagnostics

Microsoft.Extensions.Logging,

это не логгер в чистом виде. Это набор абстракций для взаимодействия логирования с DI в .Net Core. Удобный инструмент но на выходе (приемник логов, отвечающий за их сохранение) это все равно одна из перечисленных выше библиотек. В тоже время используя этот инструмент мы имеем плюсы (например универсальная работа запись в лог, не надо думать какой логгер у либ, просто передай доступ к DI или LoggerFactory) и минусы (нет кастомных плюшек присущих конкретному логгеру, на пример всякие доллары и собаки серилога уже не рекомендуются ибо при смене логгера получится фигня)

это не логгер в чистом виде. Это набор абстракций для взаимодействия логирования с DI в .Net Core. Удобный инструмент но на выходе (приемник логов, отвечающий за их сохранение) это все равно одна из перечисленных выше библиотек.

Это, прямо скажем, не так. Приложение "из коробки", с "чистым" Microsoft.Extensions.Logging, без NLog или Serilog, прекрасно пишет логи.


Консоль, Elasticsearch, Applications Insights или внутри AWS Lambda (набор несколько от балды, что в голову пришло).


Т.е., конечно, провайдеров меньше, чем у более старых фреймворков, но типовые задачи решаются.

Вообще тема интересная. Тут все становится гораздо проще, когда у вас 100500 сервисов, и каждый изначально использует какой-нибудь свой, только одному ему понятный, формат логов (у логгеров же столько прикольных настроек - хрех не воспользоваться).

А вы такой хотите видеть в этом хаосе ну хоть какое-нибудь однообразие. Плюс метаданные про сам сервис и ещё что-нибудь про межсервисные транзакции (correlation) покажите. И да, хочется чтобы вся эта толпа не устраивала вам локальный DDOS, работая под большой нагрузкой. И чтобы в логи не попадали PII.

В таком случае, мне кажется, муки выбора библиотеки сводятся к выбору вендора, с помощью которого вы будете строить observability, а все остальное он уже выбрал за вас. Мы работаем с NewRelic. Но интересно какие есть ещё аналоги?

В таком случае, мне кажется, муки выбора библиотеки сводятся к выбору вендора, с помощью которого вы будете строить observability, а все остальное он уже выбрал за вас.

Вообще, есть (или потихоньку выползает, по крайней мере) OpenTelemetry.


А еще у логгеров есть свои синки для ваших вендоров (вот, например, Serilog -> NewRelic: https://github.com/thiagobarradas/serilog-sinks-newrelic-logs).

Да вот об этом я и говорю. В итоге проект обрастает чем-то вроде вот такого и всем становится без разницы чем один логгер лучше другого когда на выходе результат одинаков.

Ну, вам без разницы, а я до сих пор эту разницу вижу, так что каждому своё.

пересел с nlog на стандартное решение Microsoft.Extensions.Logging и забыл\перестал понимать зачем другие библиотеки для этого существуют

Такой же бардак с этими библиотеками логирования, как и в Java, если честно.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории