首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BeginScope与Serilog

BeginScope与Serilog
EN

Stack Overflow用户
提问于 2019-09-04 15:45:11
回答 2查看 12.4K关注 0票数 10

我想直接使用Microsoft.Logger在Serilog上的特性,即BeginScope特性。

我知道我可以使用微软的ILogger和安装Serilog作为底层的记录器,但在这个应用程序的这一点上太麻烦了。

我想知道在Serilog中是否存在BeginScope等价物。

互联网上的信息并不是直截了当的,有人提到Serilog支持这一点,但如果直接支持它或使用Microsoft类,则没有提到任何地方。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-04 23:09:33

是的,Serilog有一个与此特性相当的本地特性,称为使用LogContext.PushProperty()

要启用此功能,首先必须将Enrich.FromLogContext()添加到Serilog LoggerConfiguration中,例如:

代码语言:javascript
复制
Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext() // <- this line
    .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} " +
                                     "{Properties:j}{NewLine}{Exception}"))
    .CreateLogger();

然后,若要将属性推送到上下文(等效于ILogger.BeginScope()),请使用:

代码语言:javascript
复制
using (LogContext.PushProperty("OrderId", 1234))
{
    Log.Information("Processing a new order");
    // ...etc
}

上面的配置包括{Properties:j},以确保输出中包含所有事件属性(例如来自日志上下文的事件属性)。如何查看附加属性将取决于您正在使用的接收器。

票数 18
EN

Stack Overflow用户

发布于 2020-12-31 14:51:58

@尼古拉斯的回答是正确的。我只想给其他人举个小例子,告诉他们一些不太明显的事情;

这里有一些示例代码,展示了如何使用Serilog上下文;

代码语言:javascript
复制
void Main()
{
    var log = Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .MinimumLevel.Information()
    .WriteTo.Console()
    
    .CreateLogger();
    Log.Logger = log;
    log.Information("Starting app");
    
    Task.WaitAll(
        Task.Run (() => GetNums(10,15, 2, "evens")),
        Task.Run (() => GetNums(11, 15, 2, "odds"))
    );
    
    log.Information("Finished.");

    Console.ReadLine();
    
}

static Random R = new Random();

static void GetNums(int start, int cnt, int inc, string name)
{
    using(var log = LogContext.PushProperty("name", name))
    {
        for (int i = start; i < start + cnt; i+=inc)
        {
            Log.Information("{number},{name}", i);
            Thread.Sleep(R.Next(500));
        }
    }
}

产生这个输出

代码语言:javascript
复制
[17:11:31 INF] Starting app
[17:11:31 INF] 10,evens
[17:11:31 INF] 11,odds
[17:11:31 INF] 12,evens
[17:11:31 INF] 14,evens
[17:11:32 INF] 13,odds
[17:11:32 INF] 16,evens
[17:11:32 INF] 15,odds
[17:11:32 INF] 18,evens
[17:11:32 INF] 20,evens
[17:11:32 INF] 17,odds
[17:11:32 INF] 22,evens
[17:11:33 INF] 24,evens
[17:11:33 INF] 19,odds
[17:11:33 INF] 21,odds
[17:11:34 INF] 23,odds
[17:11:34 INF] 25,odds
[17:11:34 INF] Finished.

我想指出的是,如果命名的值没有出现在模板中,那么记录到上下文的项不会出现在日志中(即不会被记录)。

例如,在上面的代码中,如果我们将Log.Information("{number},{name}",i);更改为Log.Information("{number}",i);,那么这就是您将得到的结果,这与您在不配置富集Enrich.FromLogContext()时可能得到的类似。这是微妙和容易忘记更新模板和追逐你的尾巴,试图找到错误。

没有模板字符串,包括上下文中包含的命名属性。

代码语言:javascript
复制
[17:22:11 INF] Starting app
[17:22:11 INF] 10
[17:22:11 INF] 11
[17:22:11 INF] 12
[17:22:11 INF] 13
[17:22:11 INF] 15
[17:22:11 INF] 17
[17:22:12 INF] 14
[17:22:12 INF] 16
[17:22:12 INF] 19
[17:22:12 INF] 18
[17:22:12 INF] 20
[17:22:12 INF] 21
[17:22:12 INF] 23
[17:22:12 INF] 22
[17:22:12 INF] 24
[17:22:13 INF] 25
[17:22:13 INF] Finished.

而且,丰富的属性是字符串末尾的appended,因此Log.Information("{name},{number}", i);将生成

代码语言:javascript
复制
[17:35:11 INF] Starting app
[17:35:11 INF] 11,{number}
[17:35:11 INF] 10,{number}

伐木愉快!希望这能帮上忙。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57791868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档