Expero.Libraries.CSharp.Logging 1.6.2

Expero.Libraries.CSharp.Logging

Пакет для работы с логированием.

Пакет содержит:

  • Middleware для логирования HTTP запросов;
  • Метод, для упрощенной регистрации Middleware и сервисов для логирования;
  • Возможность сохранения логов в ObjectStorage (S3);
  • Аттрибут, для настройки разных уровней логирования и для включения/отключения сохранения логов в S3 для разных частей конкретного endpoint;
  • Интерфейс IHttpLoggingHandler для создания собственных обработчиков логов.
  • Возможность записи в лог собственных сообщений Executing endpoint и Executied endpoint с нужным уровнем логирования;
  • Методы расширения ILogger для логирования операций;

Подключение к проекту.

Для подключения логирвания HTTP к проекту необходимо добавить сервис и зарегистрировать Middleware. Для регистрации сервисов в пакете есть 2 метода:

services.AddExperoHttpLogging(LoggingSettings).

services.AddExperoHttpLogging(Action<LoggingSettings>).

Пример добавления в проект:

public void AddService(IServiceCollection services)
{
    /*...*/
    services.AddExperoHttpLogging(settings =>
    {
        settings.RequestExecutingLevel = LogLevel.None;
        settings.RequestUrlLevel = LogLevel.Debug;
        settings.RequestQueryLevel = LogLevel.Debug;
        settings.RequestHeadersLevel = LogLevel.Debug;
        settings.RequestBodyLevel = LogLevel.Debug;
        settings.ResponseStatusCodeLevel = LogLevel.Debug;
        settings.ResponseHeadersLevel = LogLevel.Debug;
        settings.ResponseBodyLevel = LogLevel.Debug;
        settings.UseObjectStorage = true;
        settings.S3Configuration = new HttpLoggingS3Configuration
        {
            Host = "s3.expero.ru",
            Ssl = true,
            AccessKey = "sdgfertfdsafsa",
            SecretKey = "dfkxkclkwoeewrjzklfskdknvcsdhfkja",
            Bucket = new ObjectStorageS3BucketName("portal-log")
         };
    });
    /*...*/
}

public static void UseApi(this IApplicationBuilder app)
{
    /*...*/
    app.UseRouting();

    app.UseExperoHttpLogging();
    /*...*/
}

либо через создание экземпляра HttpLoggingSettings:

public void AddService(IServiceCollection services)
{
    /*...*/

    var settings = new LoggingSettings()
    {
        RequestExecutingLevel = LogLevel.None,
        RequestUrlLevel = LogLevel.Debug,
        RequestQueryLevel = LogLevel.Debug,
        RequestHeadersLevel = LogLevel.Debug,
        RequestBodyLevel = LogLevel.Debug,
        ResponseStatusCodeLevel = LogLevel.Debug,
        ResponseHeadersLevel = LogLevel.Debug,
        ResponseBodyLevel = LogLevel.Debug,
        UseObjectStorage = true,
        S3Configuration = new HttpLoggingS3Configuration
        {
            Host = "s3.expero.ru",
            Ssl = true,
            AccessKey = "sdgfertfdsafsa",
            SecretKey = "dfkxkclkwoeewrjzklfskdknvcsdhfkja",
            Bucket = new ObjectStorageS3BucketName("portal-logs")
         }
    };

    services.AddExperoHttpLogging(settings);
    
    /*...*/
}

public static void UseApi(this IApplicationBuilder app)
{
    /*...*/

    app.UseRouting();

    app.UseExperoHttpLogging();

    /*...*/
}

HttpLoggingSettings

Модель HttpLoggingSettings содержит настройки уровней логирования для разных частей запроса. Уровень логирования это стандартный enum LogLevel из Microsoft.Extensions.Logging:

  • RequestExecutingLevel - уровень логирования сообщений Executing endpoint и Executied endpoint;
  • RequestUrlLevel - уровень логирования Url;
  • RequestQueryLevel - уровень логирования Query-параметров;
  • RequestHeadersLevel - уровень логирования заголовков запроса;
  • RequestBodyLevel - уровень логирования тела запроса;
  • ResponseStatusCodeLevel - уровень логирования StatusCode ответа;
  • ResponseHeadersLevel - уровень логирования заголовков ответа;
  • ResponseBodyLevel - уровень логирования тела ответа;
  • UseObjectStorage - флаг, указывающий на необходимость сохранения в ObjectStorage;
  • S3Configuration настройки подключения к S3;

N.B. При использовании RequestExecutingLevel рекомендуется установить уровень логирования Microsoft.AspNetCore.Routing в уровень выше Information, например, None. Это отключит штатные сообщения Executing endpoint и Executied endpoint , иначе они будут дублироваться.

"Serilog": {
    "Other": {
        "Microsoft.AspNetCore.Routing": "Warning"
    }

Кроме того, необходимо добавить Middleware к приложению. Для этого надо вызвать метод UseExperoHttpLogging() у ApplicationBuilder, причем обязательно после UseRouting().

После этого, все HTTP запросы к endpoint будут логироваться с заданным уровнем.

Аттрибут [HttpLogging].

Аттрибут [HttpLogging] применяется к методам контроллера, обабатывающюм запросы для указания уровней логирования разным частям запроса. Также с помощью аттрибута можно указать, чтобы лог сохранялся в ObjectStorage.

Пример с явным указанием уровней логирования частей HTTP запроса:

/*...*/
[HttpGet]
[HttpLogging(RequestUrlLevel = LogLevel.Debug, ResponseHeadersLevel = LogLevel.Error)]
public JsonResult Get()
{
    return new JsonResult("Everything is ok");
}
/*...*/

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

Пример с явным указанием уровней логирования частей HTTP запроса:

/*...*/
[HttpGet]
[HttpLogging(LogLevel.None)]
public JsonResult Get()
{
    return new JsonResult("Everything is ok");
}
/*...*/

Пример с использованием UseObjectStorage:

Параметр UseObjectStorage позволяет явно указать конкретному запросу, надо ли сохранять в ObjectStorage лог.

/*...*/
[HttpGet]
[HttpLogging(UseObjectStorage = true)]
public JsonResult Get()
{
    return new JsonResult("Everything is ok");
}
/*...*/

Кастомный аттрибут

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

Свойства аттибута [HttpLogging]:

Чтобы указать какие части запроса каким уровнем необходимо логировать, нужно передать их в качестве параметров аттрибута [HttpLogging(...)]. При этом части запроса, которые ны были явно указаны, будут логироваться с уровнем, указанным при подключении пакета. Доступные настройки имеют те же названия, что и в настройках (IHttpLoggingSettings) при подключении:

  • RequestExecutingLevel - уровень логирования сообщений Executing endpoint и Executied endpoint;
  • RequestUrlLevel - уровень логирования Url;
  • RequestQueryLevel - уровень логирования Query-параметров;
  • RequestHeadersLevel - уровень логирования заголовков запроса;
  • RequestBodyLevel - уровень логирования тела запроса;
  • ResponseStatusCodeLevel - уровень логирования StatusCode ответа;
  • ResponseHeadersLevel - уровень логирования заголовков ответа;
  • ResponseBodyLevel - уровень логирования тела ответа;
  • UseObjectStorage - флаг, указывающий сохранение в S3 всех логов;

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

Создание собственных обработчиков логирования частей Http запроса.

Пакет содержит интерфейс IHttpLoggingHandler, у которого можно реализовать собственные методы для логирования конкретных частей запроса. Все методы реализовывавть не обязательно. Для использования достаточно зарегистрировать свой handler в DI.

/*...*/
internal class CustomHttpLoggingHandler : IHttpLoggingHandler
{
    public CustomHttpLoggingHandler() { }


    #region IHttpLoggingHandler

    void IHttpLoggingHandler.LogRequestBody(string body, LogLevel level, IHttpLoggingContext context)
    {
        Console.WriteLine(level, body, context.HttpContext.Session.Id);
    }

    #endregion IHttpLoggingHandler
}
/*...*/
public void AddService(IServiceCollection services)
{
    services.AddTransient<IHttpLoggingHandler, CustomHttpLoggingHandler>();
}

Методы для логирования операций

Основная идея это использовать механизм Dispose при завершении контекста выполнения. Мы используем это для логгировоания начала и конца операции.

Пакет содержит методы расширения интерфейса ILogger для логирования операций, так же вычисляется время выполнения:

  • ILogger.LogOperation(string, LogLevel)
  • ILogger.LogOperationTrace(string)
  • ILogger.LogOperationDebug(string)
  • ILogger.LogOperationInformation(string)
  • ILogger.LogOperationWarning(string)
  • ILogger.LogOperationError(string)
  • ILogger.LogOperationCritical(string)

Пример использования

 using var _ = _logger.LogOperationDebug($"Load matching links from master data");

Пример лога

[DBG] Start "Load matching links from masted data"
[DBG] Complete "Load matching links from masted data", elapsed: 2.13.

Методы для получения делегатов стандартных методов ILogger

Основная цель - сокращение кода для логирования в коде, чтобы логи были более чистыми и меньше захламляли рабочее пространство, иногда их становится слишком много. Методы расширения возвращают делегаты типа Logger для стандартных методов логированя (LogTrace, LogDebug и др.). Также есть универсальный метод Delegate для создания делегата логгера с любым уровнем логирования.

Пакет содержит методы расширения интерфейса ILogger для получения делегатов:

  • ILogger.TraceDelegate()
  • ILogger.DebugDelegate()
  • ILogger.InformationDelegate()
  • ILogger.WarningDelegate()
  • ILogger.ErrorDelegate()
  • ILogger.CriticalDelegate()
  • ILogger.Delegate(LogLevel)

Пример использования

Пример использование

// ...

internal sealed class PageSeoService : IPageSeoService
{
    // ...

    private readonly ILogger<PageSeoService> _logger;
    private readonly Logger _t;

    public PageSeoService(

        // ...

        ILogger<PageSeoService> logger)
    {
        // ...

        _logger = logger;
        _t = logger.TraceDelegate();
    }

    // ...

    _t("Trying get page's seo from cache.");

    // ...

Пример лога

[VRB] Trying get page's seo from cache.

Дополнительный функционал

Расширения для Activity и ActivitySource

В пакете есть функционал для упрощения работы с Activity и ActivitySource. Он нужен для того, чтобы сократить количество кода для медиаторов для трейсинга.

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

Пример использования

// ....

// Получаем источник Activity
public static class Tracing
{
    public static ActivitySource ActivitySource { get; } = typeof(Tracing).CreateAssemblyActivitySource();
}

//...

internal sealed class INomenclatureSynchronizer_Tracing : INomenclatureSynchronizer
{
    // ...

    private readonly ActivitySourceWithTag _activitySource;

    public INomenclatureSynchronizer_Tracing(INomenclatureSynchronizer decorated, ILogger<INomenclatureSynchronizer> logger)
    {
        // Оборачиываем источник, чтобы он содержал тэг
        _activitySource = Tracing.ActivitySource.WithTag(_decorated);
    }


    // ...

    public async Task ImportAsync(IEnumerable<NomenclatureContainerDto> containers, CancellationToken cancellationToken)
    {
        // Формируем активность с использование using
        using var activity = _activitySource.Start();

        // ...
        await _decorated.ImportAsync(containers, cancellationToken);
    }
}

Showing the top 20 packages that depend on Expero.Libraries.CSharp.Logging.

Packages Downloads
Expero.Libraries.CSharp.BackgroundTasks
Пакет для работы с фоновыми задачами.
1

Version Downloads Last updated
1.6.2 1 02/28/2026
1.6.1 1 02/28/2026
1.6.0 1 02/28/2026
1.6.0-beta.78716 1 02/28/2026
1.6.0-beta.78714 1 02/28/2026
1.5.0 1 02/28/2026
1.5.0-beta.65659 1 02/28/2026
1.4.2-beta.52735 1 02/28/2026
1.4.0 1 02/28/2026
1.4.0-beta.56537 1 02/28/2026
1.4.0-beta.52845 1 02/28/2026
1.3.0 1 02/28/2026
1.2.1 1 02/28/2026
1.2.0 1 02/28/2026
1.1.1-beta.46062 1 02/28/2026
1.1.1-beta.45837 1 02/28/2026
1.1.1-beta.45076 1 02/28/2026
1.1.0 1 02/28/2026
1.0.0 1 02/28/2026