使用Microsoft.Extensions.Logging.Abstractions

时间:2019-06-19 19:50:15

标签: c# logging nunit abstraction

我想根据信息登录到不同的日志文件。

应用程序日志文件应包含有关应用程序或服务行为以及异常的常规信息。

在服务内部,我想登录到应用程序日志文件,并将不适合常规日志文件的内容登录到服务日志文件。服务日志文件的示例可以是串行端口的通信。

我有一个.net核心应用程序,在其中初始化Log4Net Logger:

public void Configure(..., ILoggerFactory loggerFactory, ...)
{
    ...
    loggerFactory.AddLog4Net();
    ...
}

我的应用程序日志的log4net.config看起来像这样:

 <log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </root>
  <appender name="console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %level %logger - %message%newline" />
    </layout>
  </appender>
  <appender name="file" type="log4net.Appender.RollingFileAppender">
    <file value="logs/application.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
  <datePattern value="-yyyyMMdd" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="5MB" />
  <preserveLogFileNameExtension value="true" />
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
    </layout>
  </appender>
 </log4net>

我使用依赖注入在.net标准2.0项目中实现的服务中使用记录器。这些项目引用了Microsoft.Extensions.Logging.Abstractions nuget包。 https://github.com/aspnet/Extensions/tree/master/src/Logging/Logging.Abstractions/src

示例服务

public void MyService(ILogger<MyService> logger)
{
   logger.Log(LogLevel.Information, $"application log info");
   // How to log to the service log file?
   // logger.LogServiceLog(LogLevel.Information, $"service log info")
}

我知道我可以根据名称空间将log4net配置为登录到不同的日志文件。但是我希望能够同时使用两个日志文件。

是否可以通过Microsoft.Extensions.Logging.Abstractions实现此目的?

我可以将范围记录到另一个日志文件吗?

using (_logger.BeginScope("Service Scope"))
{
    _logger.LogInformation("Service info");
}

2 个答案:

答案 0 :(得分:0)

内置记录器不支持文件记录(尽管我认为有人基于Azure Provider进行了扩展?)我的建议是,如果您需要该级别的记录-坚持使用Log4Net

答案 1 :(得分:0)

最后,我找到了满足我需求的解决方案。 如果其他人也想这样做,我会分享。

正如我已经假设的那样,有可能通过登录示波器来实现。 必须设置范围属性,以便可以将其用于登录到其他文件。

为方便起见,我编写了一个扩展方法:

private const string PropertyKey = "ServiceLogger";
private const string ValueSuffix = "ServiceLogger";

public static void ServiceLog<TCategoryName>(this ILogger<TCategoryName> logger, LogLevel level, string message)
{
    using (logger.BeginScope(new[] { new KeyValuePair<string, object>(PropertyKey, $"{typeof(TCategoryName).Name}{ValueSuffix}") }))
    {
        logger.Log(level, message);
    }
}

现在在服务中,我可以使用:

public void MyService(ILogger<MyService> logger)
{
   // application log file
   logger.Log(LogLevel.Information, $"application log info");
   // service log file
   logger.ServiceLog(LogLevel.Information, $"service log info");
}

为了使它起作用,必须对log4net配置进行调整,因为如果设置了密钥,我想登录到其他文件。因此,我添加了一个新的附加程序,其中有一个针对Property Key = ServiceLogger和value = MyServiceServiceLogger的过滤器。

请注意,如果此日志仅应位于一个日志文件中,则必须在常规附加程序上为属性Key = ServiceLogger和包含ServiceLogger的值设置忽略过滤器。

示例配置:

<log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="console" />
    <appender-ref ref="app_logger" />
    <appender-ref ref="service_myservice_logger" />
  </root>
  <appender name="console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%2thread] %-5level %.50logger - %message%newline" />
    </layout>
  </appender>
  <appender name="app_logger" type="log4net.Appender.RollingFileAppender">
    <file value="logs/application.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="-yyyyMMdd" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="5MB" />
    <preserveLogFileNameExtension value="true" />
    <staticLogFileName value="false" />
    <filter type="log4net.Filter.PropertyFilter">
      <key value="ServiceLogger" />
      <regexToMatch value="ServiceLogger" />
      <acceptOnMatch value="false" />
    </filter>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%2thread] %-5level %.50logger - %message%newline" />
    </layout>
  </appender>
  <appender name="service_myservice_logger" type="log4net.Appender.RollingFileAppender">
    <file value="logs/my_service.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="-yyyyMMdd" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="5MB" />
    <preserveLogFileNameExtension value="true" />
    <staticLogFileName value="false" />
    <filter type="log4net.Filter.PropertyFilter">
      <Key value="ServiceLogger" />
      <StringToMatch value="MyServiceServiceLogger" />
    </filter>
    <filter type="log4net.Filter.DenyAllFilter" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%2thread] %-5level %.50logger - %message%newline" />
    </layout>
  </appender>
</log4net>