Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将我自己的属性添加到Serilog输出模板_C#_Logging_Serilog - Fatal编程技术网

C# 如何将我自己的属性添加到Serilog输出模板

C# 如何将我自己的属性添加到Serilog输出模板,c#,logging,serilog,C#,Logging,Serilog,我有一个从服务总线接收消息的小应用程序,它可以为不同的用户发送几种不同类型的事件。根据事件的类型,调用不同的函数。我在每个函数中记录信息 我目前有: var logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message}{NewLine}{Excep

我有一个从服务总线接收消息的小应用程序,它可以为不同的用户发送几种不同类型的事件。根据事件的类型,调用不同的函数。我在每个函数中记录信息

我目前有:

var logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .WriteTo.Console(outputTemplate:
        "[{Timestamp:HH:mm:ss} {Level:u3}] {Message}{NewLine}{Exception}")
    .WriteTo.Loggly()
    .CreateLogger();

...

// logging an event
Log.Information("{UserId} {Event} - Here is my message", "123", "Test Event");
这很好,但因为对于这个应用程序,每个日志都将包含日志中的用户ID和事件数据,所以我想我可以将它们添加到输出模板中,使日志代码更干净一些。所以我试过这个:

var logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .WriteTo.Console(outputTemplate:
      "[{Timestamp:HH:mm:ss} {Level:u3}] {UserId} {Event} - {Message}{NewLine}{Exception}")
    .WriteTo.Loggly()
    .CreateLogger();

...

// logging an event
Log.Information("Here is my message", "123", "Test Event");
Log.Information("Here is my message", new { UserId = "123", Event = "Test Event"});
但这两种方法都不起作用,它输出的只是我的消息,而不是通过我传递给它的用户ID或事件


我做错了吗?或者甚至有办法做到这一点吗?

如果要添加不属于消息模板的属性,则需要丰富日志上下文。这意味着添加FromLogContext enricher,并以稍微不同的方式将属性添加到记录的事件中

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .MinimumLevel.Information()
    .WriteTo.Console(outputTemplate:
    "[{Timestamp:HH:mm:ss} {Level:u3}] {UserId} {Event} - {Message}{NewLine}{Exception}")
    .CreateLogger();

using (LogContext.PushProperty("UserId", "123"))
using (LogContext.PushProperty("Event", "Test Event"))
{
    Log.Information("Here is my message about order {OrderNumber}", 567);
    Log.Information("Here is my message about product {ProductId}", "SomeProduct");
}
您可以在中了解有关充实的更多信息

现在我不确定洛格利的情况。我以前从未用过。但是,如果您使用的是Seq(Seq来自Serilog的创建者,使用它效果最好),那么您甚至不需要修改输出模板。添加的属性将自动适用于每个事件

正如Nicholas Blumhardt通过评论指出的那样,如果您只需要一次性向单个记录的事件添加属性,您也可以这样做。有时,当我有很多事件的属性,而这些属性不一定需要显示在消息中,并且只应用于单个事件时,我会这样做

Log
   .ForContext("OrderNumber", orderNumber)
   .ForContext("UserId", user.Id)
   .Information("Order submitted");

您可以使用
Enrich.WithProperty(“PropertyName”、“PropertyValue”)


但enricher值的解决方式不是不同吗?它类似于ManagedThreadId,您无法将其传递给Log.Information。Enricher实现Enrich方法,在该方法中,它们为该属性添加属性名称和值。@VidmantasBlazevicius当您使用LogContext.PushProperty时,它将向using块范围内的所有语句添加属性。如果这些属性是输出模板的一部分,它们将显示在记录的消息中。否则,它们只是日志事件上的不同属性。感谢澄清,我还得出结论,您的答案可能与OP想要的行为尽可能接近。另一个选项是
Log.ForContext(“UserId”,123)。ForContext(“event”,“Test event”)。信息(“Hello,world!”)
-但是
LogContext.PushProperty()
可能是这个用例更好的API。@NicholasBlumhardt很好的一点,我已经在答案中添加了这个例子,并解释了什么时候可以使用它。
Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Information()
                .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning)
                .MinimumLevel.Override("System", Serilog.Events.LogEventLevel.Warning)
                .WriteTo.File(new Serilog.Formatting.Json.JsonFormatter(), "D:\\Temp\\Serilogs\\structuredLog.json", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information)
                .Enrich.FromLogContext()
                .Enrich.WithMachineName()
                .Enrich.WithProcessId()
                .Enrich.WithThreadId()
                .Enrich.WithProperty("ApplicationName", "Serilogs DemoApplication")
                .CreateLogger();