Какими инструментами пользовались для логирования в C#?
Что проверяют
Знаете ли вы абстракцию ILogger и понимаете ли, зачем нужно структурированное логирование, а не запись строк в файл. Следом спрашивают, как вы искали ошибку в продакшене по логам и как связывали записи одного запроса.
Как отвечать
Начните с того, что в современном .NET код пишет в ILogger<T> из Microsoft.Extensions.Logging, а конкретная библиотека подключается провайдером. Дальше инструменты:
- Serilog: структурированные события, sinks (консоль в JSON, файл, Seq, Elasticsearch или OpenSearch, Grafana Loki), контекст через enrichers,
UseSerilogRequestLogging()для одной записи на HTTP-запрос; - NLog: зрелая библиотека с targets и rules, конфигурация в
nlog.configили в секцииNLogфайлаappsettings.json, структурные параметры тоже поддерживает; - log4net: встречается в старых проектах на .NET Framework, новые на нём обычно не начинают;
- OpenTelemetry: логи, трейсы и метрики с общим
TraceId, по которому запись в логе связывается с трассировкой запроса.
Покажите приёмы. Шаблон сообщения вместо интерполяции: logger.LogInformation("Order {OrderId} paid in {Elapsed} ms", id, ms), тогда OrderId становится полем, по которому можно искать. BeginScope добавляет контекст ко всем записям внутри блока. Для горячих путей атрибут [LoggerMessage] генерирует метод без лишних аллокаций. Уровни у стандартного логгера задаются в секции Logging:LogLevel, шум фреймворка обычно глушат до Warning.
Где спотыкаются
Пишут LogInformation($"Order {id} paid"). Структура теряется, строка собирается даже при выключенном уровне, а искать по такому логу можно только по подстроке.
Логируют исключение как ex.Message. Нужно передавать сам объект: LogError(ex, "Не удалось списать оплату {OrderId}", id), иначе пропадают стек и внутренние исключения.
Пишут в лог токены, пароли и персональные данные, например тело запроса целиком. Логи хранятся дольше и доступны шире, чем база.