如何在具有多线程的Microsoft.Extensions.Logging中包括DependencyInjection范围?

时间:2019-05-06 15:05:21

标签: c# multithreading logging dependency-injection

我做一个Task.Run(),并在其中创建一个用于依赖项注入的范围(using (var scope = serviceProvider.CreateScope()))。我想通知loggerfactory和loggers关于该范围的信息,然后将其添加到日志中。

查看源代码后,我发现loggerfactory和logger <>是单例的,这使我难以使用。如果我在一个线程中更改它,其他所有线程都将更改...

1 个答案:

答案 0 :(得分:0)

我正在使用SeriLog,并且可以通过丰富的功能实现我想要的功能。在Serilog设置中,您需要确保设置LogContext的扩充功能:

return webHost
    .UseStartup<Startup>()
    .UseSerilog((context, config) =>
    {
        config
        .ReadFrom.Configuration(context.Configuration)
        .Enrich.FromLogContext();
    });

,然后在创建DI作用域之前或之后添加所需的作用域信息:

var task = Task.Run(() =>
{
    using (Serilog.Context.LogContext.PushProperty("ExecutionScope", "MyMultithreadedScope "))
    using (var scope = app.ApplicationServices.CreateScope())
    {
        Logger.LogDebug("test");
        //....
    }
});

您还需要在Serilog outputTemplate中指定属性。例如:"{Timestamp:HH:mm:ss.fff} {ExecutionScope}{Message}"

LogContext使用AsyncLocal将信息保留在上下文中,并支持异步和多线程等控制流更改。