相关文章推荐
粗眉毛的柑橘  ·  openssh ...·  11 月前    · 

Serilog简介

与其他许多.NET库一样,Serilog还提供了对文件,控制台等的基本诊断日志记录。它易于设置,具有简洁的API,并且可以在最新的.NET平台之间移植。

使用和配置、自定义Enricher

由于 serilog 配置信息比较多,避免硬编码代码中,我们在 appsetting.jgon 同级目录中新建一个 serilogsetting.json 的日志配置文件,简单内容如下:

"Serilog" : { "Using" : [ "Serilog.Sinks.Console" , "Serilog.Sinks.Seq" ] , "MinimumLevel" : { "Default" : "Information" , "Override" : { "System" : "Error" , "Microsoft" : "Error" "WriteTo" : [ "Name" : "Console" "Name" : "Seq" , "Args" : { "serverUrl" : "http://localhost:5341/" , "apiKey" : "L2on8gpgjose5uldhdch"

更多配置内容请参考: serilog wiki 文档

接下来,在 Program.cs 中添加一个方法,初始化这些配置,然后重写下构建主机的代码:

public class Program
    public static int Main(string[] args)
        var logConfig = GetLogConfig();
        Log.Logger = new LoggerConfiguration()
                     .ReadFrom.Configuration(logConfig)
                     .Enrich.FormLogContext()
                     .CreateLogger(); 
            // web host 初始化
            var host = BuildWebHost(args);
            host.Run();
            return 0;
        catch(Exception e)
            Log.Fatal(ex, "{ApplicationContext} 出现错误:{messsage} !", AppName, ex.Message);
            return 1;
        finally
            Log.CloseAndFlush();
    /// <summary>
    /// 读取日志配置
    /// </summary>
    /// <returns></returns>
    private static IConfiguration GetLogConfig()
        var builder = new ConfigurationBuilder()
                      .AddJsonFile("serilogsetting.json", optional: false, reloadOnChange: true);
        return builder.Build();

然后,添加一个自定义Enircher,用来记录HttpContext,的数据。_enrichAction则可以自定义,默认记录ip,请求路径,请求方法,和返回响应码:

public class HttpContextEnricher:ILogEventEnricher
    private readonly IServiceProvider _serviceProvider;
    private readonly Action<LogEvent, ILogEventPropertyFactory, HttpContext> _enrichAction;
    public HttpContextEnricher(IServiceProvider serviceProvider) : this(serviceProvider, null)
    public HttpContextEnricher(IServiceProvider serviceProvider, Action<LogEvent, ILogEventPropertyFactory, HttpContext> enrichAction)
        _serviceProvider = serviceProvider;
        if (enrichAction == null)
            _enrichAction = (logEvent, propertyFactory, httpContext) =>{
                var x_forwarded_for = new StringValues();
                if (httpContext.Request.Headers.ContainsKey("X-Forwarded-For"))
                   x_forwarded_for = httpContext.Request.Headers["X-Forwarded-For"];
                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("client_ip", JsonConvert.SerializeObject(x_forwarded_for)));
                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_path", httpContext.Request.Path));
                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_method", httpContext.Request.Method));
                 if (httpContext.Response.HasStarted)
                     logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("response_status", httpContext.Response.StatusCode));
        }else{
            _enrichAction = enrichAction;
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
        var httpContext = _serviceProvider.GetService<IHttpContextAccessor>()?.HttpContext;
         if (null != httpContext){
             _enrichAction.Invoke(logEvent, propertyFactory, httpContext);

现在,我们添加了一个记录HttpContext的Enricher,但是怎么用起来呢,怎么添加到日志对象中呢。就要靠asp.net core的中间件了。新建一个HttpContextLogMiddleware中间件:

public class HttpContextLogMiddleware
    private readonly RequestDelegate _next;
    public HttpContextLogMiddleware(RequestDelegate next)
        _next = next;
    public async Task InvokeAsync(HttpContext context)
        var serviceProvider = context.RequestServices;
        // 将我们自定义的Enricher添加到LogContext中。
        // LogContext功能很强大,可以动态添加属性,具体使用介绍,参见官方wiki文档
        using (LogContext.Push(new HttpContextEnricher(serviceProvider)))
            await _next(context);
// 使用扩展方法形式注入中间件
public static IApplicationBuilder UseHttpContextLog(
    this IApplicationBuilder builder)
    return builder.UseMiddleware<HttpContextLogMiddleware>();

这样,我们就建立了一个中间件,接下来在Startup.cs的Configure方法中app.UseHttpContextLog();即可。

此处需要注意中间件的顺序,参见官方ASP.NET CORE的中间件介绍

这样,我们就添加了一个自定义的Enricher来记录请求的上下文信息。启动应用程序,看下输出结果:

分类:
后端
标签: