消息模板中未使用的属性的序列日志字段名

本文关键字:日志 字段 属性 未使用 消息 | 更新日期: 2023-09-27 18:13:58

我正在测试Serilog,并且遇到一些字段名称问题。

我想添加一个日志条目,其中一个字段包含在消息模板中,其他字段仅存储在日志中以供查询。

我想做一些简单的事情,像这样:

logger.Debug("Recalculation performed for operation {OperationId}", 
                operationId, operationTypeId, otherId, anotherId);

但是这会导致字段名没有被赋予友好的名称,因为它们不在消息模板中:

{
   "@timestamp":"2016-10-20T16:57:02.0623798+01:00",
   "level":"Debug",
   "messageTemplate":"Recalculation performed for operation {OperationId}",
   "fields":{  
      "OperationId":1024,
      "__1":16,
      "__2":32,
      "__3":256,
      "SourceContext":"SerilogTest.Worker"
   }
}

我知道我可以把所有的字段放入一个类中,并使用ForContext方法将它们包含在日志条目中:

internal class OperationData
{
    public int OperationId { get; set; }
    public int OperationTypeId { get; set; }
    public int OtherId { get; set; }
    public int AnotherId { get; set; }
}
var operationData = new OperationData
                {
                    OperationId = 1024,
                    OperationTypeId = 16,
                    OtherId = 32,
                    AnotherId = 256
                };
var operationLogger = logger.ForContext("OperationData", 
                        operationData, destructureObjects: true);
operationLogger.Debug("Recalculation performed for operation {OperationId}",
                         operationData.OperationId);

这就是我想要的结果:

{
   "@timestamp":"2016-10-20T18:00:35.4956991+01:00",
   "level":"Debug",
   "messageTemplate":"Recalculation performed for operation {OperationId}",
   "fields":{  
      "OperationId":1024,
      "OperationData":{  
         "_typeTag":"RecalulationResult",
         "OperationId":1024,
         "OperationTypeId":16,
         "OtherId":32,
         "AnotherId":256
      },
      "SourceContext":"SerilogTest.Worker"
   }
}

但是,仅仅为了有一个友好的字段名似乎要付出很多努力。我必须创建一个新的记录器实例,有一个类型,包括所有相关字段的日志消息,然后做日志。还有比这更简单的命名字段的方法吗?

消息模板中未使用的属性的序列日志字段名

匿名类型可以用更少的代码实现上面的功能:

logger
    .ForContext("Operation", new {operationTypeId, otherId, anotherId}, true)
    .Debug("Recalculation performed for operation {OperationId}", operationId);

或者在事件中包含所有内容:

logger.Debug("Recalculation performed for operation {@Operation}", new {
        Id = operationId, TypeId = operationTypeId, OtherId = otherId, 
        AnotherId = anotherId
    });

如果你发现有很多你想要包含相同属性的消息,你最好把它们推到LogContext:

using (LogContext.PushProperty("OperationId", operationId))
{
    logger.Debug("Recalculation performed");
    // ...etc...
    logger.Debug("Something else");
}

在本例中,两个事件都有一个与之关联的OperationId。您可以将多个属性推入日志上下文。只要确保将Enrich.FromLogContext()添加到LoggerConfiguration中即可使用此样式。