始终使用 serilog 记录上下文数据 [英] Always log context data using serilog

查看:99
本文介绍了始终使用 serilog 记录上下文数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Serilog 进行日志记录.对于每个日志,我想记录上下文信息,如用户名和其他一些上下文信息.所以我用下面的静态方法创建了包装器

I am using Serilog for logging. For every log i want to log context information like username and some other context information. So i created wrapper with static method as below

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 的上下文信息

this is working, but is there any better way to include context information with serilog

更新 1

所以我根据建议创建了一个丰富器

So i created an enricher based on suggestion

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 方法?

However how do i invoke it? Which With method i should be using?

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

更新 2
我已经创建了扩展方法,然后在日志配置期间使用它

Update 2
I have created extension method and then use it during logging configuration

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

然后在 Application_Start 事件中在 global.asax 中配置记录器

and then configured the logger in global.asax in Application_Start event

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

我注意到每次我记录一些东西时,都会调用丰富器并返回用户名,但它没有在日志中记录用户名.我在日志中看到了我的消息,但没有看到 UserName 属性.我正在使用 Windows EventLog Sink

I have noticed everytime i log something, enricher is getting invoked and it returns UserName but it does not log UserName in the log. I see my message in the log but not the UserName property. I am using Windows EventLog Sink

我将信息记录为

       Log.Information("Some message");

和错误为

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

我错过了什么?

推荐答案

使用 Serilog 有几种不同的方法可以做到这一点.您可以使用在应用程序开始时配置的 Enricher(当您配置logging),它会在您记录消息时自动调用,您可以将所需的其他属性添加到 Log 上下文中.

There's a few different ways to do that with Serilog. You could use an Enricher that you configure at the start of your application (when you configure logging), and it gets called automatically as you log messages and you can add the additional properties you want to the Log context.

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

Another way would be to hook into an event called by your web app framework at the beginning of each request, and then add properties to the Log context.

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

One other way, would be to add contextual properties at the moment where the logger instance is resolved by your DI container (if you're using one).

  • 更丰富的样本

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

https:///github.com/serilog-web/classic/blob/master/src/SerilogWeb.Classic/Classic/Enrichers/HttpRequestClientHostIPEnricher.cs

  • 上下文推送属性示例

https://web.archive.org/web/20171207095449/http://mylifeforthecode.com/enriching-serilog-output-with-httpcontext-information-in-asp-net-core/

  • Autofac Serilog 集成

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

这篇关于始终使用 serilog 记录上下文数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆