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

如何配置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客户端配置

通过启用格式化消息或自定义处理器,直接在客户端完成模板填充:

  1. 启用内置格式化逻辑
    只需在日志配置中开启IncludeFormattedMessage,客户端会自动将结构化日志模板替换为填充后的完整字符串,同时保留原始属性:
builder.Logging.AddOpenTelemetry(options =>
{
    options.IncludeFormattedMessage = true; // 核心配置:生成已填充的完整日志消息
    options.AddOtlpExporter(o => 
    {
        o.Endpoint = new Uri("http://your-collector-url:4317");
    });
});
  1. 自定义日志处理器(复杂场景)
    如果需要更灵活的逻辑控制,可自定义处理器处理模板替换:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 19:12:33