网易首页 > 网易号 > 正文 申请入驻

Serilog文档翻译系列(四) - 结构化数据

0
分享至

Serilog 是一种序列化器。在许多情况下,它具有良好的默认行为,能够满足其目的,但有时也需要指示 Serilog 如何存储附加到日志事件上的属性。

Serilog 使用一些不寻常的术语来指代 .NET 对象如何映射到其内部(与接收器无关的)属性表示。这些术语的详细解释如下,所以如果你打算阅读整页内容,可以跳过这一部分。

· 字符串化(Stringification)是指获取一个提供.NET 属性,并调用其 ToString() 方法,以便到达接收器的表示是一个简单的字符串。

· 解构(Destructuring)是指将复杂的 .NET 对象转换为结构的过程,这些结构可能会被表示为 JSON 对象或 XML 块。

· 标量(Scalars)是指可以表示为原子值的 .NET 类型;大多数值类型如 int 都符合这个描述,但一些引用类型如 Uri 和 string 也符合。

1、为什么需要控制表示方式?

记录对象到日志的方式可能有很多种。大多数类型可以很好地表示为字符串或简单值,但有些则更适合记录为集合,还有些则适合记录为具有命名属性的结构体。

日志事件属性的存储表示方式对日志的大小以及获取这些数据所需的内存和处理开销有很大影响。

考虑到这一点,我们来看看如何在简单情况下配置 Serilog。

2、默认行为

当在日志事件中指定属性时,Serilog 会尽力确定正确的表示方式。

简单的标量值

var count = 456;
Log.Information("Retrieved {Count} records", count);

在这种情况下,Count 属性的存储方式几乎没有歧义。作为一个简单的整数值,Serilog 会选择这种表示方式。

{ "Count": 456 }

这些示例使用 JSON,但相同的原则也适用于其他格式。

开箱即用,Serilog 识别以下列表作为基本标量类型,无论是否应用了其他策略:

· 布尔值 - bool

· 数值 - byte, short, ushort, int, uint, long, ulong, float, double, decimal

· 字符串 - string, byte[]

· 时间 - DateTime, DateTimeOffset, TimeSpan

· 其他 - Guid, Uri

· 可空类型 - 上述类型的可空版本

集合

如果作为属性传递的对象是IEnumerable,Serilog会将该属性视为集合。

var fruit = new[] { "Apple", "Pear", "Orange" };
Log.Information("In my bowl I have {Fruit}", fruit);

对应的JSON包括一个数组。

{ "Fruit": ["Apple", "Pear", "Orange"] }

Serilog 之所以这样选择,是因为大多数可枚举类型关注的是其元素,而作为结构或字符串表示不佳。

Serilog还识别Dictionary,只要键类型是上面列出的标量类型之一。

var fruit = new Dictionary {{ "Apple", 1}, { "Pear", 5 }};
Log.Information("In my bowl I have {Fruit}", fruit);

支持字典的格式器可以将属性记录为字典。

{ "Fruit": { "Apple": 1, "Pear": 5 }}

IDictionary- 实现字典接口的对象不会被序列化为字典。首先,因为在.NET中检查泛型接口兼容性效率较低,其次,一个对象可能实现多个泛型字典接口,从而产生歧义。

对象

除了上述特殊处理的类型之外,Serilog 很难智能地选择数据的渲染和持久化方式。未明确用于序列化的对象往往序列化效果很差。

SqlConnection conn = ...;
Log.Information("Connected to {Connection}", conn);

(哎呀!如何序列化一个 SqlConnection 对象?)

当 Serilog 无法识别该类型且未指定操作符(见下文)时,对象将使用 ToString() 方法进行渲染。

3、保留对象结构

在许多情况下,如果可能的话,将日志事件属性序列化为结构化对象是有意义的。数据传输对象(DTOs)、消息、事件和模型通常最好通过将其分解为具有值的属性来进行日志记录。

为此,Serilog 提供了 @ 解构操作符。

var sensorInput = new { Latitude = 25, Longitude = 134 };
Log.Information("Processing {@SensorInput}", sensorInput);

(“解构”一词是从各种编程语言中借用的;它是一种用于从结构化数据中提取值的模式匹配风格。目前,Serilog 中的用法仅与该术语在概念上相关,但未来对该运算符的扩展可能会更准确地匹配其更广泛的定义。)

自定义存储的数据

通常,对复杂对象的只有部分属性是感兴趣的。要自定义 Serilog 如何持久化解构的复杂类型,可以在 LoggerConfiguration 上使用 Destructure 配置对象:

Log.Logger = new LoggerConfiguration()
.Destructure.ByTransforming(
r => new { RawUrl = r.RawUrl, Method = r.Method })
.WriteTo...

这个示例将HttpRequest类型的对象转换为仅保留RawUrl和Method属性的新对象。可以使用多种不同的解构策略,也可以通过实现 IDestructuringPolicy 创建自定义策略。

注意:提供给 Destructure.ByTransforming() 的函数必须返回与传入类型不同的类型,否则会递归调用。可以使用自定义的 IDestructuringPolicy 来实现条件转换。

操作符与格式

虽然操作符和格式都影响属性的表示方式,但它们的作用是不同的。操作符在捕获属性时被应用,用于以某种方式保留或结构化数据。而格式则仅在将属性显示为文本时使用,不会影响序列化的表示。

格式化集合和结构

当为复杂属性指定格式字符串时,它们通常会被忽略。只有可枚举类型会考虑格式字符串,并在显示时将其传递给元素。

4、强制字符串化

有时,日志记录的对象类型可能不完全确定,或者可能以不希望在日志事件中保留的方式变化。在这些情况下,$ 字符串化操作符将把属性值转换为字符串,然后再进行其他处理,无论其类型或实现的接口是什么。

var unknown = new[] { 1, 2, 3 }
Log.Information("Received {$Data}", unknown);

尽管 unknown 是一个枚举类型,但它被捕获并以字符串形式呈现。

Received "System.Int32[]"

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

声明:个人原创,仅供参考

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
快船大甩卖!哈登祖巴茨全送走,不是摆烂?美媒:他们还要冲季后赛!

快船大甩卖!哈登祖巴茨全送走,不是摆烂?美媒:他们还要冲季后赛!

生活新鲜市
2026-02-07 00:17:34
笑死!给宠物取名字一定要慎重,网友:我喊的时候路人以为我疯了

笑死!给宠物取名字一定要慎重,网友:我喊的时候路人以为我疯了

另子维爱读史
2026-02-04 23:11:29
上海警方:“落难公子”王某某已被拘留!

上海警方:“落难公子”王某某已被拘留!

环球网资讯
2026-02-06 08:38:01
寿命短的男性,常有“2大2白1斑”,如果没有,说明身体很健康

寿命短的男性,常有“2大2白1斑”,如果没有,说明身体很健康

轩辕岛
2025-12-20 11:45:03
连续5个交易日一字跌停!近23亿元排队出逃,国投瑞银白银LOF深夜变净值估算标准后,终于正式回应,支持投资者依法解决诉求

连续5个交易日一字跌停!近23亿元排队出逃,国投瑞银白银LOF深夜变净值估算标准后,终于正式回应,支持投资者依法解决诉求

金融界
2026-02-06 18:30:33
美国媒体圈震动,有人惊呼:这是“谋杀”

美国媒体圈震动,有人惊呼:这是“谋杀”

环球时报国际
2026-02-06 21:02:08
什么世道?大学教授说真话,竟被院里警告…

什么世道?大学教授说真话,竟被院里警告…

慧翔百科
2026-01-27 11:35:19
奉劝大家:过年别买这6种年货,全都是科技,白送都别要!

奉劝大家:过年别买这6种年货,全都是科技,白送都别要!

复转这些年
2026-02-03 23:47:02
iPhone17e定档:2月19日,即将亮相

iPhone17e定档:2月19日,即将亮相

3C毒物
2026-02-06 00:05:42
订婚宴上婆婆骂我下三滥,我笑着问公公:你儿子做过亲子鉴定吗?

订婚宴上婆婆骂我下三滥,我笑着问公公:你儿子做过亲子鉴定吗?

千秋文化
2026-01-29 21:30:14
52岁复出屠榜?这位阿姨才是真正的业界钢铁侠!

52岁复出屠榜?这位阿姨才是真正的业界钢铁侠!

素然追光
2026-01-06 05:50:03
张本智和遭网暴!日媒:恶心、丑八怪、退役吧等恶语中伤奥运选手

张本智和遭网暴!日媒:恶心、丑八怪、退役吧等恶语中伤奥运选手

颜小白的篮球梦
2026-02-04 05:55:29
1967年,梁兴初厉声质问副政委:邓华你也敢动?谁给你的胆子?

1967年,梁兴初厉声质问副政委:邓华你也敢动?谁给你的胆子?

鉴史录
2026-02-05 16:28:29
哈登被冤枉了?骑士GM:并非主动申请离队,快船又一次掩盖事实

哈登被冤枉了?骑士GM:并非主动申请离队,快船又一次掩盖事实

只扣篮的教练
2026-02-06 10:23:29
越南披露中越战争内幕,坦言中国若迟撤军五日,谅山主力将被全歼

越南披露中越战争内幕,坦言中国若迟撤军五日,谅山主力将被全歼

磊子讲史
2026-02-04 12:02:50
人有苦相,缺陷突出:福薄之人,吃饭时都有这3个特征,注定劳碌一生

人有苦相,缺陷突出:福薄之人,吃饭时都有这3个特征,注定劳碌一生

古怪奇谈录
2026-01-04 14:10:12
福建一村党总支原书记、村委会主任涉嫌严重违纪违法被查

福建一村党总支原书记、村委会主任涉嫌严重违纪违法被查

大闽门户
2026-02-06 19:17:15
刚回国的留子,战斗力有多强?网友:给小吃摊老板吓哭了!

刚回国的留子,战斗力有多强?网友:给小吃摊老板吓哭了!

夜深爱杂谈
2026-01-27 18:24:46
苏-57神话破灭!被吹上天的“隐身战机”,实则是大号三代机

苏-57神话破灭!被吹上天的“隐身战机”,实则是大号三代机

老马拉车莫少装
2026-02-06 00:00:23
U19国青队1:0绝杀乌兹别克斯坦,中国男足曙光初现?

U19国青队1:0绝杀乌兹别克斯坦,中国男足曙光初现?

魔血獄苼
2026-02-07 00:55:24
2026-02-07 02:11:00
IT规划师
IT规划师
热爱编程,追求最佳实践,喜欢思想的碰撞
78文章数 906关注度
往期回顾 全部

科技要闻

独角兽版图巨变:SpaceX奔万亿 中美差在哪

头条要闻

女生被51岁推拿技师猥亵:没等到道歉 还遭网暴

头条要闻

女生被51岁推拿技师猥亵:没等到道歉 还遭网暴

体育要闻

西甲射手榜第2,身价不到姆巴佩1/40

娱乐要闻

微博之夜抢C风波 杨幂工作室9字讨说法

财经要闻

爱尔眼科董事长旗下7家精神病院骗保

汽车要闻

宝马"本命年"关键词:20款新车与"新世代"耐力赛

态度原创

游戏
教育
旅游
数码
公开课

T2总裁回应GTA6争议:给他爱新DLC力证老作热度不减

教育要闻

为什么留学机构没有好的老师?

旅游要闻

琅琊古城·“文旅迎春 马跃新程”2026河东文旅新春联欢晚会举行

数码要闻

炒作退潮+需求疲软,DDR4高价难续,降价窗口期已至

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版