JavaRush /Курсы /C# SELF /Логирование: Microsoft.Ext...

Логирование: Microsoft.Extensions.Logging

C# SELF
64 уровень , 0 лекция
Открыта

1. Введение

В программировании логирование — это не просто "вывести что-нибудь в консоль". Логирование — это ваш чёрный ящик, GPS-трекер и индикатор в одном флаконе. Без логов большая программа становится чёрным ящиком-загадкой: "почему сервис завис?", "почему пользователь не получил письмо?", "а вообще хоть кто-нибудь запускал этот модуль за последние 3 месяца?" — на все эти вопросы часто можно ответить только если логи хранятся и доступны.

Зачем логирование нужно в реальности?

Поиск и диагностика ошибок
Если программа упала — логи расскажут, где и почему. Если не упала, но работает странно — логи укажут шаги, которые к этому привели.

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

Безопасность
Логирование попыток неавторизованного доступа, подозрительной активности, ошибок аутентификации.

Аудит
Кто, что и когда сделал. Если уволился злой админ и удалил данные, по логам можно всё восстановить (или хотя бы понять, что именно он сделал).

Поддержка в разработке и эксплуатации
Логи — это не только для программиста, но и для тестировщика, оператора, админа. Через полгода вы сами скажете себе: 'Спасибо, что добавил логи!'

От Console.WriteLine до промышленного логирования

Первая реакция новичка: "А что, просто Console.WriteLine не хватает?". Для маленьких учебных программ этого действительно достаточно. Но когда приложение запускается на сервере, работает параллельно, или его используют десятки и сотни пользователей, консоль уже не помощник. Нужно:

  • Разделять важную информацию и отладочную.
  • Отправлять логи не только в консоль, но и в файлы, базы данных, централизованные системы.
  • Изменять уровень подробности логов (минимум — только ошибки, максимум — всё подряд).
  • Автоматически дополнять записи датой, временем, дополнительной информацией.
  • Гибко конфигурировать.
  • А главное — не менять код заново, чтобы перенаправить логи в другое место.

Здесь-то и начинается эпоха "настоящих" логгеров.

2. Основы современной системы логирования в .NET

В экосистеме .NET существует стандартный, мощный и гибкий фреймворк для логирования — Microsoft.Extensions.Logging. Это часть всей "новой волны" .NET библиотек, появившихся вместе с ASP.NET Core, но используется теперь везде: и на сервере, и в десктопе, и даже в мобильных приложениях.

Чем хорош этот фреймворк?

  • Абстракция — не привязывает вас к конкретной реализации (логгер может писать в файл, консоль, в облако, или одновременно во всё подряд).
  • Поддержка уровней логирования (Trace, Debug, Information, Warning, Error, Critical).
  • Встраивание в DI-контейнер и интеграция во все современные .NET приложения.
  • Богатая экосистема расширений: поддержка структурированного логирования, продвинутых форматтеров и интеграций.

Основные понятия и классы

Давайте познакомимся с ключевыми объектами, которые понадобятся нам для работы с Microsoft.Extensions.Logging:

Класс/Интерфейс Назначение
ILogger<T>
Интерфейс для логирования, типизированный по классу
ILogger
Обобщённый интерфейс логгера
ILoggerFactory
Фабрика создания экземпляров логгеров
ILoggingBuilder
Позволяет настраивать логирование в приложении
LogLevel
Перечисление уровней логов (Trace, Debug, Information, ...)

Уровни логирования

Разделение сообщений по уровню важности позволяет фильтровать "шум" и искать нужное:

Уровень (LogLevel) Для чего использовать?
Trace
Максимально подробная отладка, "шум", временные данные
Debug
Основная отладочная информация
Information
Ключевые событийные сообщения для нормальной работы
Warning
Предупреждения о потенциальных проблемах, но система продолжает
Error
Ошибки, которые требуют внимания, но приложение живо
Critical
Критические сбои, угрожающие всей системе

3. Практика: добавляем логирование в наше приложение

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

Пример: базовый калькулятор

public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
    // Остальные методы...
}

Теперь встроим в него логирование. Для этого нам нужен интерфейс ILogger<Calculator>, который мы будем получать извне (например, через Dependency Injection, DI).

using Microsoft.Extensions.Logging;

public class Calculator
{
    private readonly ILogger<Calculator> _logger;

    public Calculator(ILogger<Calculator> logger)
    {
        _logger = logger;
    }

    public int Add(int a, int b)
    {
        int result = a + b;
        _logger.LogInformation("Выполнено сложение: {A} + {B} = {Result}", a, b, result);
        return result;
    }
}

Интересный факт:
Вместо конкатенации строк логгеры поддерживают шаблоны и именованные параметры ({A}, {B}, {Result}), что позволяет делать логи структурированными и удобными для последующей автоматической обработки и поиска.

4. Как создать и настроить логгер в консольном приложении

1. Подключаем NuGet-пакеты

В вашем проекте потребуется:

  • Microsoft.Extensions.Logging
  • Microsoft.Extensions.Logging.Console (если хотим писать в консоль)
  • (опционально) другие провайдеры, если нужно

2. Конфигурируем логгер

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

// Создаём DI-контейнер
var serviceProvider = new ServiceCollection()
    .AddLogging(builder => {
        builder.AddConsole(); // Вывод в консоль
        builder.SetMinimumLevel(LogLevel.Debug); // Минимальный уровень логов
    })
    .BuildServiceProvider();

// Получаем экземпляр логгера нужного типа
var logger = serviceProvider.GetRequiredService<ILogger<Calculator>>();

var calculator = new Calculator(logger);
calculator.Add(5, 3); // В логи попадёт сообщение

Типичная ошибка новичков
"Почему лог не появляется в консоли?" — проверьте, добавлен ли нужный провайдер (.AddConsole()) и правильно ли указан минимальный уровень логирования (SetMinimumLevel). Если уровень выше, сообщения могут просто "отфильтровываться"!

5. Полезные нюансы

Логируем ошибки и нестандартные ситуации

Допустим, мы хотим залогировать деление на ноль. Добавим соответствующий метод:

public int Divide(int a, int b)
{
    if (b == 0)
    {
        _logger.LogError("Попытка деления на ноль! a={A}", a);
        throw new DivideByZeroException();
    }
    int result = a / b;
    _logger.LogInformation("Выполнено деление: {A} / {B} = {Result}", a, b, result);
    return result;
}

Зачем это нужно?
В реальном приложении, когда что-то идёт не так, логи с уровнем Error обычно привлекают особое внимание: они автоматически отправляются админам, подсвечиваются в мониторинге и используются для алертов/оповещений.

Использование категорий и меток (scopes)

Логгер в .NET поддерживает так называемые scopes — это дополнительные метаданные, которые автоматически добавляются ко всем логам в течение определённого блока кода. Например, если вы обрабатываете веб-запрос или пользовательский сеанс, можно добавить его идентификатор в scope.

using (_logger.BeginScope("UserId: {UserId}", 42))
{
    _logger.LogInformation("Началась обработка данных пользователя");
    // ...
}

Все сообщения внутри блока получат дополнительную метку UserId: 42, что позже поможет находить логи по пользователям или операциям.

Пример: уровни логирования в действии

_logger.LogTrace("Это Trace — почти никто не увидит");
_logger.LogDebug("Это Debug — для разработчиков");
_logger.LogInformation("Это Information — для событий обычной работы");
_logger.LogWarning("Это Warning — предупреждение о возможной проблеме");
_logger.LogError("Это Error — ошибка, требующая внимания");
_logger.LogCritical("Это Critical — Система горит, нужен пожарный!");

Если вы настроили SetMinimumLevel(LogLevel.Information), то увидите только сообщения уровней Information, Warning, Error, Critical.

Фишка:
Оставляйте логи Trace и Debug для подробной диагностики на этапе разработки, а на боевом сервере чаще всего включают только Information и выше, чтобы не раздувать размер логов и не упустить важное среди "шума".

Визуальная схема: архитектура современного логирования

graph TD
A[Код приложения] --ILogger<YourClass>--> B[Microsoft.Extensions.Logging]
B --> C1[Console Provider]
B --> C2[File Provider]
B --> C3[Cloud/Database Provider]
C1 -.-> D1[Логи в консоль]
C2 -.-> D2[Логи в файл]
C3 -.-> D3[Логи в систему мониторинга]

subgraph Providers
    C1
    C2
    C3
end

6. Дополнительные возможности и расширения

Структурированное логирование:
Значения параметров можно хранить не только в строке, но и в виде ключ-значение, что делает возможным поиск и агрегацию по этим параметрам (например, через Seq, ELK/ElasticSearch или Application Insights).

Провайдеры логирования:
Можно добавить десятки разных провайдеров: файловый, для Windows EventLog, Azure и т.д.

Конфигурирование логирования через appsettings.json
В ASP.NET Core логи гибко конфигурируются по файлу конфигурации, без перекомпиляции приложения.

Пример настройки минимального уровня логирования через конфиг (appsettings.json):

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "MyApp.Calculator": "Debug",
      "Microsoft": "Warning"
    }
  }
}

7. Типичные ошибки при работе с Microsoft.Extensions.Logging

Ошибка №1: Неправильный выбор уровня логирования.
Использование LogInformation для ошибок вместо LogError или LogCritical затрудняет поиск проблем в продакшене.

Ошибка №2: Игнорирование структурированного логирования.
Конкатенация строк вместо шаблонов с плейсхолдерами ({Parameter}) лишает преимуществ структурированного логирования, таких как поиск по параметрам.

Ошибка №3: Неправильная настройка уровней логирования.
Если минимальный уровень логов установлен выше нужного (например, Warning вместо Debug), важные сообщения могут быть отфильтрованы.

Ошибка №4: Избыточное или недостаточное логирование.
Слишком подробные логи (например, Trace в продакшене) создают "шум", а отсутствие логов затрудняет диагностику.

2
Задача
C# SELF, 64 уровень, 0 лекция
Недоступна
Базовое логирование с использованием 'Microsoft.Extensions.Logging'
Базовое логирование с использованием 'Microsoft.Extensions.Logging'
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ