You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Worker Service中Serilog LogEvent的MessageTemplateToken创建问题

关于Serilog DuplicateFilterSink重复计数消息空白的问题

我在C# .NET 8 Worker Service项目中基于Serilog实现了DuplicateFilterSink,用来过滤连续重复的日志:连续出现相同LogEvent时只计数不输出,当新的LogEvent到来且重复计数大于0时,先输出“前一条消息重复X次”的日志,再输出新消息,避免循环日志占满文件。目前功能基本正常,但输出的重复计数消息内容是空的。我推测原因是创建MessageTemplate时用了空的MessageTemplateToken数组,由于MessageTemplateToken是抽象类无法直接实例化,且现有LogEvent的MessageTemplateToken文本不可修改,因此有两个疑问:

  1. 是否是空MessageTemplateToken数组导致输出空白行?
  2. 如何创建包含有效MessageTemplateToken数组的合法MessageTemplate?

问题解答

1. 空MessageTemplateToken数组是否导致空白行?

是的,这就是导致空白行的直接原因。Serilog的MessageTemplate完全依赖内部的MessageTemplateToken数组来渲染最终的日志文本,当数组为空时,没有任何可解析输出的内容,自然会输出空白行。

2. 如何创建合法的MessageTemplate?

不需要手动实例化MessageTemplateToken的子类,Serilog内置了MessageTemplateParser工具类,通过它的静态Parse方法可以直接将字符串解析为合法的MessageTemplate,该方法会自动生成对应的MessageTemplateToken数组。

示例代码如下:

using Serilog.Events;
using Serilog.Parsing;
using System.Linq;

// 假设重复计数为count
int count = 3;
// 定义重复提示消息
var repeatMessage = $"前一条消息重复{count}次";
// 解析生成合法的MessageTemplate
var template = MessageTemplateParser.Parse(repeatMessage);

// 创建对应的LogEvent
var repeatLogEvent = new LogEvent(
    timestamp: DateTimeOffset.Now,
    level: LogEventLevel.Information,
    exception: null,
    messageTemplate: template,
    properties: Enumerable.Empty<LogEventProperty>()
);

// 将该LogEvent输出到目标Sink(比如你原本的输出Sink)
yourTargetSink.Emit(repeatLogEvent);

如果需要保留原日志的上下文属性,也可以将原LogEvent的Properties传递给新创建的repeatLogEvent,保证日志上下文的一致性。


内容的提问来源于stack exchange,提问作者Dogulas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:46:00