Работали ли вы с системами логирования?

Ответ

Да, работал с различными библиотеками и системами для сбора, структурирования и анализа логов.

Стек и практики:

  1. Библиотеки в .NET:

    • Serilog: Современный стандарт де-факто. Позволяет использовать структурированное логирование (JSON) и множество "стоков" (sinks).
    • NLog / log4net: Классические, мощные библиотеки.
    • ILogger<T> из Microsoft.Extensions.Logging: Абстракция, поверх которой работают Serilog, NLog и др.
  2. Пример настройки Serilog с выводом в консоль и файл (JSON):

    // Program.cs (ASP.NET Core 6+)
    using Serilog;
    
    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Information()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // Снижаем шум от фреймворка
        .Enrich.FromLogContext() // Добавляем контекст (например, TraceId)
        .WriteTo.Console(new JsonFormatter()) // JSON в консоль
        .WriteTo.File("logs/app-.json", rollingInterval: RollingInterval.Day) // JSON в файл
        .CreateLogger();
    
    var builder = WebApplication.CreateBuilder(args);
    builder.Host.UseSerilog(); // Подключаем Serilog как провайдера
  3. Структурированное логирование (ключевая практика):

    // Вместо интерполяции строки (плохо для анализа)
    _logger.LogInformation($"User {userId} ordered product {productId}");
    
    // Используем именованные параметры (хорошо)
    _logger.LogInformation("User {UserId} ordered product {ProductId}", userId, productId);
    // В лог попадет: {"@t":"...","@m":"User 123 ordered product 456","UserId":123,"ProductId":456}
  4. Централизованный сбор логов (ELK/EFK Stack, Seq, Application Insights):

    • Цель: Агрегация логов со всех инстансов приложения в одном месте для поиска и анализа.
    • Пример с Seq:
      .WriteTo.Seq("http://localhost:5341")
    • Пример с Application Insights:
      builder.Services.AddApplicationInsightsTelemetry();
      // Логи ILogger автоматически отправляются как трассировки (traces).

Важные аспекты:

  • Уровни логирования: Debug, Info, Warning, Error, Critical. Важно правильно выбирать уровень.
  • Контекст: Добавление CorrelationId/RequestId для отслеживания цепочек запросов.
  • Производительность: Избегать дорогих операций (например, сериализации объектов) при отключенном уровне логирования. Используйте Logger.IsEnabled(LogLevel.Debug).
  • Не логировать конфиденциальные данные (PII, пароли, токены).

Ответ 18+ 🔞

А, ну логирование, да? Ну, это ж святое, блядь. Без этого вообще нихуя не понятно, что у тебя там в проде творится. Как слепой котёнок.

Работал, конечно, с этим всем. Ну, стандартная история: сначала пишешь Console.WriteLine("Всё охуенно!"), а потом понимаешь, что нихуя не охуенно, и начинаешь искать, где же эта сука ошибка зарылась.

Чем обычно пользуюсь и как:

  1. Библиотеки в .NET:

    • Serilog — это сейчас, блядь, вообще король. Все на него перешли. Удобный, структурированные логи пишет, и куда угодно их вывести можно — в консоль, в файл, в какую-нибудь облачную помойку.
    • NLog / log4net — старички, конечно, но ещё пыхтят. Мощные, но иногда такая конфигурация, что волосы дыбом встают. Как древние свитки, ёпта.
    • ILogger<T> — это типа официальная абстракция от Майкрософта. Под капотом у неё обычно Serilog или NLog сидит. Удобно, потому что от вендора не зависишь.
  2. Вот тебе живой пример настройки Serilog, чтоб в консоль и в файл JSON лилось:

    // Program.cs (ASP.NET Core 6+)
    using Serilog;
    
    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Information()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // А это чтобы убрать трепотню фреймворка, а то он спамит как сумасшедший
        .Enrich.FromLogContext() // Чтоб всякие TraceId цеплялись к логам
        .WriteTo.Console(new JsonFormatter()) // JSON'ом в консоль
        .WriteTo.File("logs/app-.json", rollingInterval: RollingInterval.Day) // И в файлик, который каждый день новый
        .CreateLogger();
    
    var builder = WebApplication.CreateBuilder(args);
    builder.Host.UseSerilog(); // Говорим хосту: "Друг, используй Serilog, забей на стандартный"
  3. А вот самый важный пункт, блядь! Структурированное логирование. Запомни раз и навсегда: не пихай данные в строку, а то потом их нихуя не вытащить. Сравни:

    // Так делать — пиздец как не надо. Для анализа это просто кусок текста.
    _logger.LogInformation($"User {userId} ordered product {productId}");
    
    // А вот так — правильно, красиво, мать твою. Параметры именованные.
    _logger.LogInformation("User {UserId} ordered product {ProductId}", userId, productId);
    // На выходе будет чистая JSON'ка: {"@t":"...","@m":"User 123 ordered product 456","UserId":123,"ProductId":456}
    // Потом в том же Seq или Elastic'е ты по `UserId` отфильтруешь за секунду.
  4. Ну и куда это всё слать? В консоль — это для дебага. В продакшене нужен централизованный сбор.

    • ELK/EFK Stack (Elasticsearch, Logstash/Fluentd, Kibana) — это, можно сказать, промышленный стандарт. Мощно, но и возни с ним овердохуища.
    • Seq — штука проще, для .NET-ников почти родная. Поднял докером и всё.
      .WriteTo.Seq("http://localhost:5341")
    • Application Insights — если вся твоя хуйня в Azure живёт, то очень удобно. Логи, метрики, трассировка — всё в одном месте.
      builder.Services.AddApplicationInsightsTelemetry();
      // И всё, логи с ILogger сами туда попрут.

На что ещё смотреть надо, чтоб не обосраться:

  • Уровни (Debug, Info, Warning, Error) — не лей всё подряд в Information. Debug — для разработки, Warning — когда что-то подозрительное, но не критичное, Error — когда всё, пиздец, надо срочно смотреть.
  • Контекст — обязательно пихай в логи CorrelationId, чтобы можно было все действия одного запроса собрать в кучу. Иначе будешь как дурак по миллиону строк ползать.
  • Производительность — если у тебя уровень Debug выключен, а ты там целые объекты сериализуешь для лога, то ты конченый идиот. Всегда проверяй if (_logger.IsEnabled(LogLevel.Debug)).
  • Данные — НИКОГДА, блядь, НИКОГДА не логируй пароли, токены, номера карт и прочую приватную хуйню. Тебя потом найдут и убьют.