首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Serilog文档翻译系列(五) - 编写日志事件

编程知识
2024年09月24日 21:43

日志事件通过 Log 静态类或 ILogger 接口上的方法写入接收器。下面的示例将使用 Log 以便语法简洁,但下面显示的方法同样可用于接口。

Log.Warning("Disk quota {Quota} MB exceeded by {User}", quota, user);

通过此日志方法创建的警告事件将具有两个相关属性,Quota 和 User。假设 quota 是一个整数,user 是一个字符串,呈现的消息可能如下所示。

Disk quota 1024 MB exceeded by "nblumhardt"

(Serilog 使用双引号渲染字符串值,以更清晰地指示其底层数据类型,并使属性值从周围的消息文本中脱颖而出。)

01、消息模板语法

上述字符串 “Disk quota {Quota} exceeded by {User}” 是一个 Serilog 消息模板。消息模板是标准 .NET 格式字符串的超集,因此任何适用于 string.Format() 的格式字符串也会被 Serilog 正确处理。

  • 属性名称用 { 和 } 括起来书写。
  • 属性名称必须是有效的 C# 标识符,例如 FooBar,但不能是 Foo.Bar 或 Foo-Bar。
  • 括号可以通过重复书写来转义,例如 {{ 将被渲染为 {。
  • 使用数字属性名称的格式,如 {0} 和 {1},将通过将属性名称视为索引来与日志方法的参数匹配;这与 string.Format() 的行为相同。
  • 如果任何属性名称是非数字,则所有属性名称将从左到右与日志方法的参数进行匹配。
  • 属性名称可以带有可选的运算符前缀 @ 或 $,以控制属性的序列化方式。
  • 属性名称可以带有可选的格式后缀,例如 :000,以控制属性的渲染方式;这些格式字符串的行为与 string.Format() 语法中的对应部分完全相同。

02、消息模板推荐

流畅风格指南:好的 Serilog 事件使用属性名称作为消息内容,如上面的用户示例。这提高了可读性,并使事件更简洁。

句子与片段:日志事件消息是片段,而不是句子;为了与其他使用 Serilog 的库保持一致,尽量避免使用句末的句号。

模板与消息:Serilog 事件关联的是消息模板,而不是消息。内部,Serilog 会解析并缓存每个模板(直到固定大小限制)。将日志方法的字符串参数视为消息,如下例所示,会降低性能并消耗缓存内存。

//不推荐
Log.Information("The time is " + DateTime.Now);

相反,始终使用模板属性在消息中包含变量

// 推荐
Log.Information("The time is {Now}", DateTime.Now);

属性命名:属性名称应使用 PascalCase,以保持与 Serilog 生态系统中其他代码和库的一致性。

03、日志事件级别

Serilog 使用级别作为分配日志事件重要性的主要手段。级别按重要性递增的顺序为:

  • 详细信息(Verbose) - 跟踪信息和调试细节;通常仅在特殊情况下开启。
  • 调试(Debug) - 内部控制流和诊断状态转储,以便于定位已知问题。
  • 信息(Information) - 对外部观察者有意义或相关的事件;默认启用的最低日志级别。
  • 警告(Warning) - 可能问题或服务/功能下降的指示。
  • 错误(Error) - 指示应用程序或连接系统中的失败。
  • 致命(Fatal) - 导致应用程序完全失败的严重错误。

1、信息级别的作用

信息级别与其他指定级别不同-它没有特定的语义,许多方面上表达了其他级别的缺失。

由于 Serilog 允许对应用程序的事件流进行处理或分析,信息级别可以视为事件的同义词。也就是说,大多数有趣的应用程序事件数据应记录在此级别。

2、级别检测

在大多数情况下,应用程序应该在不检查当前日志级别的情况下记录事件。级别检查的开销非常小,而调用禁用的日志记录方法的开销也很低。

在少数性能敏感的情况下,推荐的级别检测模式是将级别检测的结果存储在一个字段中,例如:

readonly bool _isDebug = Log.IsEnabled(LogEventLevel.Debug);

可以在写入日志事件之前高效地检查 _isDebug 字段:

if (_isDebug) Log.Debug("Someone is stuck debugging...");

3、动态级别

许多大型或分布式应用需要在相对限制的日志级别下运行,例如信息级(我更倾向于这种)或警告级,并仅在检测到问题时将日志级别提高到调试级或详细级,以便收集更多数据的开销是合理的。

如果应用需要动态切换日志级别,第一步是在配置日志记录器时创建一个 LoggingLevelSwitch 的实例:

var levelSwitch = new LoggingLevelSwitch();

该对象默认将当前最低级别设置为信息级,因此为了使日志记录更为严格,可以提前设置其最低级别:

levelSwitch.MinimumLevel = LogEventLevel.Warning;

在配置日志记录器时,使用 MinimumLevel.ControlledBy() 提供该开关:

var log = new LoggerConfiguration()
  .MinimumLevel.ControlledBy(levelSwitch)
  .WriteTo.ColoredConsole()
  .CreateLogger();

现在,写入日志记录器的事件将根据开关的 MinimumLevel 属性进行过滤。

要在运行时调整日志级别,例如响应通过网络发送的命令,可以更改该属性:

levelSwitch.MinimumLevel = LogEventLevel.Verbose;
log.Verbose("This will now be logged");

04、源上下文

Serilog 和大多数 .NET 日志框架一样,允许事件带上其来源标签,通常是写入这些事件的类的名称:

var myLog = Log.ForContext<MyClass>();
myLog.Information("Hello!");

写入的事件将包含一个属性 SourceContext,其值为 "MyNamespace.MyClass",可以用来过滤噪音事件或选择性地将其写入特定的接收器。

并非所有附加到事件的属性都需要在消息模板或输出格式中表示;所有属性都存储在底层 LogEvent 对象的字典中。

有关过滤器和日志记录拓扑的更多信息,请参阅《Serilog文档翻译系列(三) - 基础配置》知识。

05、关联

正如 ForContext() 会将日志事件标记为写入它们的类,ForContext() 的其他重载允许日志事件用标识符进行标记,这些标识符随后可以支持与该标识符关联的事件的关联。

var job = GetNextJob();
var jobLog = Log.ForContext("JobId", job.Id);
jobLog.Information("Running a new job");
job.Run();
jobLog.Information("Finished");

在这里,两个日志事件都将携带 JobId 属性,其中包含作业标识符。

提示:当记录到使用文本格式的接收器时,例如 Serilog.Sinks.Console,可以在输出模板中包含 {Properties} 来打印出所有未包含的上下文属性。

注:相关源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Planner

From:https://www.cnblogs.com/hugogoos/p/18430233
本文地址: http://www.shuzixingkong.net/article/2281
0评论
提交 加载更多评论
其他文章 k8s StorageClass 存储类
目录一、概述1、StorageClass 对象定义2、StorageClass YAML 示例二、StorageClass 字段1、provisioner(存储制备器)1.1、内置制备器1.2、第三方制备器2、reclaimPolicy(回收策略)3、allowVolumeExpansion(允许卷
k8s StorageClass 存储类 k8s StorageClass 存储类 k8s StorageClass 存储类
ModbusRTU通信协议报文剖析
前言 大家好!我是付工。前面给大家介绍了Modbus协议的应用层面。终于有人把Modbus说明白了那么,今天跟大家聊聊关于Modbus协议报文的那些事。 一、真实案例 前段时间有个粉丝朋友,让我帮他解决一个问题。 这个粉丝朋友是负责Modbus主站调试的。 项目背景:这是一个船舶的项目,主站是一个贝
ModbusRTU通信协议报文剖析 ModbusRTU通信协议报文剖析 ModbusRTU通信协议报文剖析
PasteForm最佳CRUD实践,实际案例PasteTemplate详解(一)
本文将介绍soft.pastecode.cn出品的PasteForm,PasteForm是贴代码使用Dto思想实现的CRUD的一个组件,或者说输出一个思想! 为啥我觉得是最佳的CRUD呢?先结合你的实际项目解答下以下问题: 1.如果有一个系统,有100个表,你的管理端需要多少页面?别和我说100个表
PasteForm最佳CRUD实践,实际案例PasteTemplate详解(一) PasteForm最佳CRUD实践,实际案例PasteTemplate详解(一) PasteForm最佳CRUD实践,实际案例PasteTemplate详解(一)
项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持windows、linux、国产麒麟系统)
需求 1.使用osg三维引擎进行动力学模型仿真性能测试; 2.打开动力学仿真模型文件,.k后缀的模型文件,测试加载解析过程; 3.解决第三方company的opengl制作的三维引擎,绘制面较多与弹丸路径模拟较卡顿的问题; 4.测试时,使用的模型为公开模型,基础面数量达到160多万个; 5.测试时,
项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持windows、linux、国产麒麟系统) 项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持windows、linux、国产麒麟系统) 项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持windows、linux、国产麒麟系统)
线程状态转换?创建线程的几种方式?线程如何停止?
线程状态转换 新建(New) NEW:初始状态,线程被构建,但是还没有调用start()方法。 可运行(Runnable) RUNNABLE:可运行状态,可运行状态可以包括:运行中状态和就绪状态。也就是 可能正在运行,也可能正在等待 CPU 时间片。 包含了操作系统线程状态中的 Running 和
线程状态转换?创建线程的几种方式?线程如何停止? 线程状态转换?创建线程的几种方式?线程如何停止? 线程状态转换?创建线程的几种方式?线程如何停止?
我是如何开发一款支持IDEA、PyCharm、Android Sutdio 等JB全家桶的摸鱼插件的
公众号「古时的风筝」,专注于后端技术,尤其是 Java 及周边生态。 个人博客:www.moonkite.cn 大家好,我是风筝 前些天做了一款支持 Jetbrains 大部分 IDE 的摸鱼插件- 一款IDE摸鱼插件,没想到出乎意料的没什么人用,当初说 VsCode 里面的养宠物的插件时,一大堆人
我是如何开发一款支持IDEA、PyCharm、Android Sutdio 等JB全家桶的摸鱼插件的 我是如何开发一款支持IDEA、PyCharm、Android Sutdio 等JB全家桶的摸鱼插件的 我是如何开发一款支持IDEA、PyCharm、Android Sutdio 等JB全家桶的摸鱼插件的
从零开始学机器学习——了解回归
在本文中,我们探讨了回归分析在统计学和数据分析中的重要性和应用。线性回归和逻辑回归作为两种主要的回归分析方法,分别适用于不同类型的数据建模和预测需求。通过数学建模,它们能够揭示变量之间的关系,并且在实际应用中展现了强大的预测能力。
从零开始学机器学习——了解回归 从零开始学机器学习——了解回归 从零开始学机器学习——了解回归
ArgoWorkflow教程(五)---Workflow 的多种触发模式:手动、定时任务与事件触发
上一篇我们分析了argo-workflow 中的 archive,包括 流水线GC、流水线归档、日志归档等功能。本篇主要分析 Workflow 中的几种触发方式,包括手动触发、定时触发、Event 事件触发等。 1. 概述 Argo Workflows 的流水线有多种触发方式: 手动触发:手动提交一
ArgoWorkflow教程(五)---Workflow 的多种触发模式:手动、定时任务与事件触发 ArgoWorkflow教程(五)---Workflow 的多种触发模式:手动、定时任务与事件触发 ArgoWorkflow教程(五)---Workflow 的多种触发模式:手动、定时任务与事件触发