NLog, .net core: как получить доступ к определенному регистратору в моей службе с помощью внедрения зависимостей

#c# #.net-core #dependency-injection #nlog

#c# #.net-core #внедрение зависимостей #nlog

Вопрос:

Версии программного обеспечения:

  • .NET Core v5.0
  • NLog v4.7.6
  • Microsoft Extensions Logging v5
  • VisualStudio2019

Я использую NLog вместе с расширениями ведения журнала Microsoft в моем консольном приложении .net core.

Приложение содержит несколько служб, которые работают в фоновом режиме как размещенные службы.

Каждая служба имеет доступ к своему типизированному регистратору, который устанавливается в ее конструкторе с помощью обычного внедрения зависимостей. Но мне также нужно добавить доступ к специальному регистратору электронной почты, который будет отправлять электронное письмо при критических исключениях. Есть ли какой-либо другой способ внедрить специальный регистратор в мой сервер вместо его создания из «NLog.LogManager.getLogger()» в каждой службе?

     public class TestService: IHostedService
    {
        private readonly ILogger<TestService> _logger;
        private readonly ILogger _emailOnFatalError;

        public TestService(ILogger<TestService> logger)
        {
            _logger = logger;
            //_emailOnFatalError = (ILogger) NLog.LogManager.GetLogger("emailOnFatalError");
        }
    }
 

Комментарии:

1. Насколько я помню, вы можете направлять разные уровни журнала в разные источники регистратора в NLog, поэтому просто настройте отправку фатального уровня журнала на электронную почту, а все остальные — в файл. Итак, _logger. LogFatal будет отправлен на электронную почту, _logger. LogInformation — в файл

2. @IvanKhorin, да, это возможно, но я не хочу отправлять все фатальные сообщения журнала на электронную почту, только небольшое подмножество тех, которые требуют немедленного внимания со стороны команды разработчиков.

3. Хорошо, используйте фильтры с инструкцией «когда» <when condition="contains('${message}','URGENT!!!:')" action="Ignore" /> и просто используйте шаблон для отправки очень срочных сообщений по электронной почте. Вторая идея — вызвать NLog. LogManager. getLogger(«emailOnFatalError»); в разделе конфигурации и введите результат, например, как одноэлементный.

Ответ №1:

Вместо того, чтобы использовать ILogger в качестве конструктора-параметра, используйте ILoggerFactory:

 public class TestService: IHostedService
{
    private readonly ILogger _logger;
    private readonly ILogger _emailOnFatalError;

    public TestService(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger(GetType().ToString());
        _emailOnFatalError = loggerFactory.CreateLogger("emailOnFatalError");
    }
}
 

В качестве альтернативы рассмотрите возможность добавления свойства события, подобного этому:

 _logger.LogError("Something awful - {EmailAlert}", "Important");
 

Затем вы можете использовать фильтрацию NLog только для отправки событий журнала, которые содержат ${event-property:EmailAlert} :

 <logger name="*" writeTo="emailOnFatalError" minLevel="Error">
   <filters defaultAction="Log">
      <when condition="'${event-property:EmailAlert}' == ''" action="Ignore" />
   </filters>
 </logger>