如何配置OpenTelemetry链路实现ASP.NET Core日志模板属性自动填充?
问题描述
我运行着一个ASP.NET Core应用,使用dotnet opentelemetry客户端,将所有事件发送至OpenTelemetry Collector实例,该实例会将事件存储到ElasticSearch和Prometheus中。目前已在ElasticSearch(可在Kibana中查看)获取到日志事件,其中某ES文档体属性如下:
Executed action method {ActionName}, returned result {ActionResult} in {ElapsedMilliseconds}ms.
请问是否可配置链路中的某一环节,利用事件属性填充该模板,以便在日志中查看类似如下的完整内容:
Executed action method Corp.Service.Controllers.Controller.StoreEvent (Corp.Service), returned result Microsoft.AspNetCore.Mvc.NoContentResult in 4.32ms.
解决方案
完全可以实现,推荐从以下两个环节配置:
一、在ASP.NET Core应用的OpenTelemetry客户端配置
通过启用格式化消息或自定义处理器,直接在客户端完成模板填充:
- 启用内置格式化逻辑
只需在日志配置中开启IncludeFormattedMessage,客户端会自动将结构化日志模板替换为填充后的完整字符串,同时保留原始属性:
builder.Logging.AddOpenTelemetry(options => { options.IncludeFormattedMessage = true; // 核心配置:生成已填充的完整日志消息 options.AddOtlpExporter(o => { o.Endpoint = new Uri("http://your-collector-url:4317"); }); });
- 自定义日志处理器(复杂场景)
如果需要更灵活的逻辑控制,可自定义处理器处理模板替换:
builder.Logging.AddOpenTelemetry(options => { options.AddOtlpExporter(o => o.Endpoint = new Uri("http://your-collector-url:4317")); options.AddProcessor(new ActionLogTemplateProcessor()); }); public class ActionLogTemplateProcessor : BaseProcessor<LogRecord> { public override void OnEnd(LogRecord logRecord) { if (logRecord.Body is string template && template.Contains("{ActionName}")) { var actionName = logRecord.Attributes.TryGetValue("ActionName", out var val) ? val.ToString() : "Unknown"; var actionResult = logRecord.Attributes.TryGetValue("ActionResult", out var resVal) ? resVal.ToString() : "Unknown"; var elapsedMs = logRecord.Attributes.TryGetValue("ElapsedMilliseconds", out var timeVal) ? timeVal.ToString() : "0"; logRecord.Body = string.Format(template, actionName, actionResult, elapsedMs); } base.OnEnd(logRecord); } }
二、在OpenTelemetry Collector中配置
无需修改应用代码,通过Collector的transform处理器在链路中间完成模板填充:
在Collector配置文件(otel-collector-config.yaml)中添加如下配置:
processors: transform: log_statements: - context: log statements: # 替换模板占位符为对应属性值 - replace_pattern(body, '{ActionName}', attributes["ActionName"]) where attributes["ActionName"] != nil - replace_pattern(body, '{ActionResult}', attributes["ActionResult"]) where attributes["ActionResult"] != nil - replace_pattern(body, '{ElapsedMilliseconds}', attributes["ElapsedMilliseconds"]) where attributes["ElapsedMilliseconds"] != nil service: pipelines: logs: receivers: [otlp] processors: [transform] exporters: [elasticsearch, prometheus]
验证
配置完成后重启应用和Collector,在Kibana中查看新生成的ES文档,即可看到填充后的完整日志内容。
内容的提问来源于stack exchange,提问作者Zyberzero
相关产品推荐
相关产品推荐

