Serilog的例外解构

 83984246_42dbe6 发布于 2022-12-28 09:28

Serilog有一种方便的对象解构方法,如下例所示:

logger.Debug(exception, "This is an {Exception} text", exception);
logger.Debug(exception, "This is an {@Exception} structure", exception);

第一行导致记录器将异常记录为纯文本(通过调用ToString()),第二行使记录器将异常属性写为单独的字段.但是这个重载呢:

logger.Debug(exception, "This is an exception", exception);

这个作为第一个参数使用异常,它总是写成一个字符串.我想要做的是以结构化的方式启用日志记录异常.是否可以配置Serilog来实现这一目标?

UPDATE.我想这个问题会导致记录异常的另一个方面:如何确保使用异常属性来丰富消息(因此它们以结构化的方式记录到富散问件,如Elasticsearch),而无需将所有异常属性写入呈现的文本消息(所以纯文本记录器没有大量的异常细节).

2 个回答
  • 看一下Serilog.Exceptions日志异常详细信息和Exception.ToString()中未输出的自定义属性.

    此库具有自定义代码,用于处理大多数常见异常类型的额外属性,并且只有在内部Serilog.Exceptions不支持异常时才会使用反射来获取额外信息.

    添加NuGet包,然后像这样添加richher:

    using Serilog;
    using Serilog.Exceptions;
    
    ILogger logger = new LoggerConfiguration()
        .Enrich.WithExceptionDetails()
        .WriteTo.Sink(new RollingFileSink(
            @"C:\logs",
            new JsonFormatter(renderMessage: true))
        .CreateLogger();
    

    现在,您的JSON日志将补充详细的异常信息甚至自定义异常属性.下面是从EntityFramework记录DbEntityValidationException时会发生什么的示例(此异常因深度嵌套的自定义属性而臭名昭着.ToString()).

    try
    {
        ...
    }
    catch (DbEntityValidationException exception)
    {
        logger.Error(exception, "Hello World");
    }
    

    上面的代码记录了以下内容:

    {
      "Timestamp": "2015-12-07T12:26:24.0557671+00:00",
      "Level": "Error",
      "MessageTemplate": "Hello World",
      "RenderedMessage": "Hello World",
      "Exception": "System.Data.Entity.Validation.DbEntityValidationException: Message",
      "Properties": {
        "ExceptionDetail": {
          "EntityValidationErrors": [
            {
              "Entry": null,
              "ValidationErrors": [
                {
                  "PropertyName": "PropertyName",
                  "ErrorMessage": "PropertyName is Required.",
                  "Type": "System.Data.Entity.Validation.DbValidationError"
                }
              ],
              "IsValid": false,
              "Type": "System.Data.Entity.Validation.DbEntityValidationResult"
            }
          ],
          "Message": "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.",
          "Data": {},
          "InnerException": null,
          "TargetSite": null,
          "StackTrace": null,
          "HelpLink": null,
          "Source": null,
          "HResult": -2146232032,
          "Type": "System.Data.Entity.Validation.DbEntityValidationException"
        },
        "Source": "418169ff-e65f-456e-8b0d-42a0973c3577"
      }
    }
    

    Serilog.Exceptions支持.NET标准并支持许多常见的异常类型而没有反射但我们想添加更多,所以请随时贡献.

    顶尖 - 人类可读堆叠痕迹

    您可以使用Ben.Demystifier NuGet包为您的异常获取人类可读的堆栈跟踪,或者如果您使用Serilog,则可以使用serilog -enrichers-demystify NuGet包.

    2022-12-28 09:29 回答
  • 有一个讨论这个的论坛帖子,其中提出了几个解决方案.Thomas Bolon创建了一个你可以在Gist中找到的"异常解构"扩展.

    在这种情况下,您只使用以下语法:

    logger.Debug(exception, "This is an exception");
    

    无需将异常添加到格式字符串中.

    要确保将异常打印到文本接收器,请确保{Exception}包含在输出模板中.标准内置的已经有了这个,例如:

    outputTemplate: "{Timestamp} [{Level}] {Message}{NewLine}{Exception}";
    

    2022-12-28 09:32 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有