Pull to refresh

Comments 11

Спасибо за интересное и полезное решение. Даже один IsEnabled уже стоит того, чтобы использовать подобный подход и не вычислять строку не зависимо от уровня логгирования. Или я ошибаясь и библиотеках логгирования тоже есть подобный механизм позволяющий не вычислять интерполяционные строки для не соответсвующего уровня?

Обычно, где-то внутри ILogger идёт проверка if(IsEnabled(level)), и если не включён уровень - ничего не вычисляется, и не логируется.

Например вот: https://source.dot.net/#Microsoft.Extensions.Logging.Console/ConsoleLogger.cs,38

При работе с FormattableString аналогично, тк она в принципе никогда в настоящую строку не собирается.

Да, внутри Logger проверка само-собой есть. Вот только, если мы даже будем использовать обычный метод ILog.LogInformation(string template, param object[] args), то массив args все равно будет аллоцирован, ведь проверка - она уже где-то там внутри.

Если же мы с этим же методом попробуем использовать интерполированную строку, то получим по факту вызов вида LogInformation(string.Format(template, args), Array.Empty<string>()). А значит выполним сначала весьма дорогой вызов string.Format, а потом уже, внутри, просто выкинем его результат на свалку.

Так что для высокопроизводительного логирования проверять вручную IsEnabled все равно может иметь смысл. И те самые новые source generators это тоже делают, равно как и предложенный мной подход.

А есть бенчмарки?

Вроде ещё до C# 10 можно было сделать структурное логирование на интерполированных строках, при помощи FormattableString:

https://github.com/Drizin/InterpolatedLogging

Интересно было бы увидеть сравнение в производительности.

А ещё есть вариант на source generators, но это немного не то: https://github.com/dotnet/designs/blob/main/accepted/2021/logging-generator.md

Постараюсь вскоре добавить бенчмарки и обновить статью.

Source generators я в тексте статьи упоминал, да и вторая ссылка в конце статьи ведет на материал про них.

Как и обещал, добавил бенчмарки.

У структурного логирования есть еще один, не самый очевидный, побочный эффект:

Если хранилище логов индексирует все свойства сообщения (как это, например, делает Elasticsearch с настройками по-умолчанию), то увеличение количества структурированных сообщений будет сказываться на производительности хранилища.

Да, на эту статью ведет вторая ссылка в конце.

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

Меня удивляет, что это происходит только последние годы, хотя самому понятию (и Serilog) уже едва не 10 лет. Даже если не использовать структурное хранилище, а просто сливать в текстовые логи - как минимум логирование упрощается. А еще можно использовать scopes, в них тоже есть destructuring. Вот про InterpolatedStringHandler не знал, спасибо, увы, мы пока еще на VS 2019.

Согласен, меня тоже это удивляет.

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

Sign up to leave a comment.

Articles