2017-02-21 143 views
1

我正在使用Serilog进行记录。对于每个日志我想记录上下文信息,如用户名和其他上下文信息。所以我创建的包装用静态方法如下始终使用serilog记录上下文数据

public static class MyLogger 
{  
    public static void Error(Exception ex, string messageTemplate, params object[] propertyvalues) 
    { 
     var properties = new List<object>(propertyvalues); 
     if (HttpContext.Current != null && HttpContext.Current.User != null && HttpContext.Current.User.Identity != null) 
     { 
      var contextInfo = new 
      {      
       UserName = HttpContext.Current.User.Identity.Name 
      }; 
      messageTemplate += "{@ContextInfo}"; 
      properties.Add(contextInfo); 
     } 

     //serilog log 
     Log.Error(ex, messageTemplate, properties.ToArray()); 
    } 
} 

然后该错误记录为

 MyLogger.Error(exception,"{@SomeMetadata}",metadata); 

这是工作,但有没有更好的办法,包括与serilog上下文信息

UPDATE1

所以我根据建议创建了一个浓缩器

public class HttpContextEnricher: ILogEventEnricher 
{ 
    LogEventProperty _cachedProperty; 

    public const string EnvironmentUserNamePropertyName = "UserName"; 

    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) 
    { 
     _cachedProperty = _cachedProperty ?? propertyFactory.CreateProperty(EnvironmentUserNamePropertyName, GetUserName()); 
     logEvent.AddPropertyIfAbsent(_cachedProperty); 
    } 

    private string GetUserName() 
    { 
     if (HttpContext.Current != null && HttpContext.Current.User != null && HttpContext.Current.User.Identity != null) 
     { 
      return HttpContext.Current.User.Identity.Name; 
     } 

     return string.Empty; 
    } 
} 

但是,我如何调用它?我应该使用哪种方法With

Log.Logger = new LoggerConfiguration() 
      .Enrich.With??????? 
      .ReadFrom.AppSettings() 
      .CreateLogger(); 

更新2
我已经创建扩展方法,然后登录配置

public static class HttpContextLoggerConfigurationExtensions 
{ 
    public static LoggerConfiguration WithUserName(
     this LoggerEnrichmentConfiguration enrichmentConfiguration) 
    { 
     if (enrichmentConfiguration == null) throw new ArgumentNullException(nameof(enrichmentConfiguration)); 
     return enrichmentConfiguration.With<HttpContextEnricher>(); 
    } 
} 

过程中使用它,然后配置的记录器中的global.asax在Application_Start事件

Log.Logger = new LoggerConfiguration() 
      .Enrich.WithUserName() 
      .ReadFrom.AppSettings() 
      .CreateLogger(); 

我注意到每次我登录的东西,丰富被调用,它返回UserName但它不记录用户名在日志中。我在日志中看到我的消息,但不是UserName属性。我使用Windows EventLog Sink

我登录的

 Log.Information("Some message"); 

和错误信息

 Log.Error(exception, "ErrorID={ErrorID}",someid); 

我失去了什么?

回答

3

用Serilog有几种不同的方法。您可以使用在应用程序开始时配置的Enricher(配置日志记录时),并且在您记录消息时它会自动调用,并且可以将所需的其他属性添加到Log上下文。

另一种方法是在每个请求开始时将钩子挂入Web应用程序框架调用的事件,然后将属性添加到日志上下文中。

另一种方法是在DI容器(如果使用的话)解析记录器实例时添加上下文属性。


  • 富集样品

https://github.com/serilog-web/owin/blob/master/src/SerilogWeb.Owin/Owin/RequestContextMiddleware.cs

http://sourcebrowser.io/Browse/serilog/serilog/src/Serilog.Extras.Web/Extras/Web/Enrichers/HttpRequestClientHostIPEnricher.cs


  • 语境PushProperty示例

http://mylifeforthecode.com/enriching-serilog-output-with-httpcontext-information-in-asp-net-core/


  • Autofac Serilog集成

https://github.com/nblumhardt/autofac-serilog-integration

+0

感谢。这是我正在寻找的确切的东西。更新我的代码以使用richher,但它不记录任何内容。请参阅更新1和2 – LP13

+0

我不确定事件日志接收器允许您指定输出模板;对于控制台,您只需在输出模板中包含“{用户名}”以将其打印在每行上。 –