Пути к файлам Serilog с управлением версиями

Я новичок в управлении версиями моего API. Я использую ASP.NET 6.0 и Serilog для записи в файл журнала.

Теперь, когда я реализовал управление версиями, я хочу, чтобы версия 1.0 приложения записывалась в «Logs/V1.0/logfile.json», а версия 2.0 записывалась в «Logs/v2.0/logfile.json».

Я могу без проблем получить номер версии «1.0» или «2.0» внутри своих контроллеров.

[ApiController]
[Route("/v{version:apiVersion}/[controller]")]
[ApiVersion("2.0")]
public class MainController : Controller

    [HttpGet]
    public void MyMethod(ApiVersion version)
    {
        _logger.LogInformation("APIVersion: {ApiVersion}", version);
    }
}

Я вижу, что Serilog сохранит эту переменную «ApiVersion» в свойствах журнала.

"Properties":{
   "ApiVersion":"2.0",
   "RequestPath":"/v2.0/Main/MyMethod",
   ...

Итак, как мне собрать все это вместе, чтобы Serilog сохранял журналы в разных местах файлов?

Я думаю, что это может иметь какое-то отношение к «Log.Logger = new LoggerConfiguration ()» в Program.cs? Я читал о различных вариантах, таких как .WriteTo.Map или Write.To.Conditional?

Все, кажется, связано с записью журналов разных уровней (информационных, предупреждений, предупреждений) в разные места. Я также понятия не имею, какой будет лучшая практика для этой настройки.

Любая помощь приветствуется!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
106
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать Serilog.Sinks.Map.

Ниже приведена рабочая демонстрация, вы можете обратиться к ней.

Установите Serilog.AspNetCore , Serilog.Sinks.Map и Microsoft.AspNetCore.Mvc.Versioning NuGet Package.

Добавьте Serilog в файл appsetting.json:

"Serilog": {
    "Using": [ "Serilog.Sinks.File" ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Error",
        "System": "Debug"
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ]
}

В Program.cs:

var logger = new LoggerConfiguration().WriteTo.Map(
                    "ApiVersion",
                    "(None)",
                    (ApiV, wt) =>
                        wt.File($"Your Path\\Logs\\{ApiV}\\logfile.json")
                    )
  .ReadFrom.Configuration(builder.Configuration)
  .Enrich.FromLogContext()
  .CreateLogger();
builder.Logging.ClearProviders();
builder.Logging.AddSerilog(logger);

builder.Services.AddApiVersioning();
//...

Контроллер:

[Route("/v{version:apiVersion}/[controller]")]
[ApiVersion("2.0")]
[ApiController]
public class MainController : ControllerBase
{
    private readonly ILogger<MainController> _logger;
    public MainController(ILogger<MainController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public void MyMethod(ApiVersion version)
    {
        _logger.LogInformation("APIVersion: {ApiVersion}", "V"+version);
    }
}

Результат испытаний:

Обновлять:

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

var basePath = "C:\\...Path\\ProjectName";

var logger = new LoggerConfiguration().WriteTo.Map(
                    "ApiVersion",
                    "(None)",
                    (ApiV, wt) =>
                        wt.File($"{basePath}\\Logs\\{ApiV}\\logfile.json")
                    )
  .ReadFrom.Configuration(builder.Configuration)
  .Enrich.FromLogContext()
  .CreateLogger();

Большое спасибо за подробный ответ. Я просто не могу заставить его работать, хотя, ха-ха-ха, я думаю, что это может быть связано с используемым путем к файлу. var basePath = AppContext.BaseDirectory; а затем wt.File($"{basePath}Logs\\{ApiV}\\logfile.json")

Scottish Smile 10.04.2023 15:09

Завтра поеду еще :)

Scottish Smile 10.04.2023 15:10

Привет @Scottish Smile, я обновил ответ на основе кода, который вы прокомментировали. Пожалуйста, проверь это.

Chen 11.04.2023 08:32

Спасибо, это работает! У меня было две проблемы: 1) некоторый дополнительный код serilog из моего старого внедрения в другом месте в program.cs, который мне пришлось удалить 2) Правильное написание пути к файлу. Ты спас меня, Чен, я с ума сходил! Еще раз спасибо :)

Scottish Smile 11.04.2023 12:55

Я сделал это так (я не добавлял .Map, как указано выше)

var version = GetVersion();
//Logger configuration
      .WriteTo.Logger(lc => lc
                .MinimumLevel.Verbose()
                .WriteTo.File(
                    path: Path.Combine(AppContext.BaseDirectory, "Logs", version, "Log.log"),
//...rest

Спасибо, Джаз, но мне нужны два отдельных пути (с двумя отдельными файлами) по одному для каждой из разных версий API. Ваш код будет регистрировать все версии в один и тот же файл?

Scottish Smile 11.04.2023 12:46

Я не понимаю, почему. Вы можете получить версию в методе GetVersion(). Вы можете сделать это через контроллер или значение атрибута. Почему вы имеете в виду, что это будет одно и то же значение?

Jazz. 11.04.2023 19:27

Ах, извините, я не заметил переменную версии.

Scottish Smile 13.04.2023 01:29

Как будет работать GetVersion()? Я понятия не имею, как на самом деле получить номер версии внутри Program.cs

Scottish Smile 13.04.2023 01:36

Другие вопросы по теме