如何让 serilog 丰富器与依赖注入一起工作,同时保持启动? [英] How do I get a serilog enricher to work with dependency injection while keeping it on startup?

查看:8
本文介绍了如何让 serilog 丰富器与依赖注入一起工作,同时保持启动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里有一个答案:我该怎么做将依赖项传递给 Serilog Enricher? 这说明您可以传递一个实例.

There is an answer here: How do I pass a dependency to a Serilog Enricher? which explains you can pass an instance in.

但是,我需要在依赖注入代码运行后(在 startup.cs 中)移动我的记录器设置

However to do that I would need to move my logger setup after my dependency injection code has ran (in the startup.cs)

这意味着不会记录启动错误,因为记录器还没有准备好.

This means that startup errors won't be logged because the logger won't be ready yet.

有没有办法以某种方式将 serilog 配置为在我的 Main() 方法中运行,但也可以使用 DI 项来丰富数据?DI 项虽然是单例,但有更多的依赖关系(主要是数据库连接).

Is there a way to somehow configure serilog to run in my Main() method, but also enrich data with a DI item? The DI item has further dependencies (mainly on database connection) although it is a singleton.

我已经用谷歌搜索了这个并阅读了一些关于将内容添加到上下文中的内容,但我一直无法找到一个我可以适应的完整工作示例.

I've googled this and read something about adding things to a context, but I've been unable to find a complete working example that I can adapt.

我发现的大多数示例都涉及将代码放入控制器以附加信息,但我希望这对每个日志条目都是全局可用的.

Most of the examples I've found involve putting code into the controller to attach information, but I want this to be globally available for every single log entry.

我的 Main 以 :

My Main starts with :

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri(elasticUri))
    {
        AutoRegisterTemplate = true,
    })
    .CreateLogger();

在进入 .NET Core MVC 代码之前

Before going into the .NET Core MVC code

CreateWebHostBuilder(args).Build().Run();

我的 DI 对象基本上是一个UserData"类,其中包含用户名、公司 ID 等.这些属性是在访问时访问数据库以获取基于某些当前身份的值的属性(尚未实现).它被我的 DI 注册为单例.

My DI object is basically a "UserData" class that contains username, companyid, etc. which are properties that hit the database when accessed to get the values based on some current identity (hasn't been implemented yet). It's registered as a singleton by my DI.

推荐答案

我建议使用插入 ASP .NET Core 管道的简单中间件,以丰富 Serilog 的 LogContext 使用所需的数据,使用所需的依赖项,让 ASP .NET Core 依赖项注入为您解决依赖项...

I would suggest using a simple middleware that you insert in the ASP .NET Core pipeline, to enrich Serilog's LogContext with the data you want, using the dependencies that you need, letting the ASP .NET Core dependency injection resolve the dependencies for you...

例如假设 IUserDataService 是一个服务,您可以使用它来获取您需要的数据,以丰富日志,中间件看起来像这样:

e.g. Assuming IUserDataService is a service that you can use to get the data you need, to enrich the log, the middleware would look something like this:

public class UserDataLoggingMiddleware
{
    private readonly RequestDelegate _next;

    public UserDataLoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context, IUserDataService userDataService)
    {
        var userData = await userDataService.GetAsync();

        // Add user data to logging context
        using (LogContext.PushProperty("UserData", userData))
        {
            await _next.Invoke(context);
        }
    }
}

上面的

LogContext.PushProperty 正在做丰富,在当前执行的日志上下文中添加一个名为 UserData 的属性.

LogContext.PushProperty above is doing the enrichment, adding a property called UserData to the log context of the current execution.

只要您在 Startup.ConfigureServices 中注册了 IUserDataService,ASP .NET Core 就会负责解析它.

ASP .NET Core takes care of resolving IUserDataService as long as you registered it in your Startup.ConfigureServices.

当然,要让它发挥作用,您必须:

Of course, for this to work, you'll have to:

1.通过调用 Enrich.FromLogContext() 告诉 Serilog 从 Log 上下文中丰富日志.例如

1. Tell Serilog to enrich the log from the Log context, by calling Enrich.FromLogContext(). e.g.

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(Configuration)
    .Enrich.FromLogContext() // <<======================
    .WriteTo.Console(
        outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} " +
                        "{Properties:j}{NewLine}{Exception}")
    .CreateLogger();

2.在 Startup.Configure 中将中间件添加到管道中.例如

2. Add your middleware to the pipeline, in your Startup.Configure. e.g.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ...

    app.UseMiddleware<UserDataLoggingMiddleware>();

    // ...

    app.UseMvc();
}

这篇关于如何让 serilog 丰富器与依赖注入一起工作,同时保持启动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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