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

无法在Grafana Tempo中获取OpenTelemetry手动日志问题

问题描述

我按照OpenTelemetry的.NET快速入门指南操作,已通过Docker部署Grafana Tempo,成功捕获所有链路追踪数据(包括HTTP调用、异常及数据库查询),可在Grafana Tempo explorer中查看。为测试,我在Swagger中创建了4个路由,当前遇到的问题:通过_logger.LogInformation("hello")等方式输出的手动日志能在控制台正常显示,但无法在Grafana Tempo中检索到。

相关代码如下:

日志接口代码

// My SendLogs endpoint
[HttpGet("SendLogs")]
public void SendLogs()
{
    _logger.LogInformation("Info log");
    _logger.LogTrace("Trace log");
    _logger.LogDebug("Debug log");
    _logger.LogWarning("Warning log");
    _logger.LogError("Error log");
    _logger.LogCritical("Critical log");
}

Program.cs配置代码

//...
builder.Services.AddOpenTelemetry()
    .WithTracing(tracerProviderBuilder =>
        tracerProviderBuilder
            .AddSource(DiagnosticsConfig.ActivitySource.Name)
            .ConfigureResource(resource => resource.AddService(DiagnosticsConfig.ServiceName))
            .AddAspNetCoreInstrumentation(options =>
            {
                options.RecordException = true;
            })
            .AddConsoleExporter()
            .AddOtlpExporter()
            .AddNpgsql()
    )
    .WithMetrics(metricsProviderBuilder => 
        metricsProviderBuilder
            .ConfigureResource(resource => resource.AddService(DiagnosticsConfig.ServiceName))
            .AddAspNetCoreInstrumentation()
            //.AddConsoleExporter()
            .AddOtlpExporter()
);

builder.Services.AddEntityFrameworkNpgsql().AddDbContext<ApiDbContext>(opt =>
{
    opt.UseNpgsql(builder.Configuration.GetConnectionString("SampleDbConnection"));
});

builder.Logging.ClearProviders();

ResourceBuilder resourceBuilder = ResourceBuilder.CreateDefault().AddService(DiagnosticsConfig.ServiceName);

builder.Logging.AddOpenTelemetry(options =>
{
    options
    .SetResourceBuilder(resourceBuilder)
    .AddConsoleExporter()
    .AddOtlpExporter();
});

builder.Services.Configure<OpenTelemetryLoggerOptions>(opt =>
{
    opt.IncludeScopes = true;
    opt.ParseStateValues = true;
    opt.IncludeFormattedMessage = true;
});
//...
解决方案

1. 明确Grafana Tempo的定位

Tempo是链路追踪存储系统,本身不直接存储日志。日志需要先发送到支持日志存储的系统(比如Loki、Elasticsearch),再通过Grafana关联Tempo的追踪数据进行检索。如果想让日志和链路关联显示,必须确保日志包含Trace ID和Span ID。

2. 配置日志自动注入追踪上下文

修改OpenTelemetry日志配置,让日志自动携带Trace ID和Span ID,同时将日志发送到日志存储系统:

步骤1:安装必要NuGet包

以Loki作为日志存储为例,安装相关包:

Install-Package OpenTelemetry.Exporter.OpenTelemetryProtocol
Install-Package Grafana.Loki.LoggerProvider

步骤2:调整Program.cs日志配置

builder.Logging.ClearProviders();

ResourceBuilder resourceBuilder = ResourceBuilder.CreateDefault().AddService(DiagnosticsConfig.ServiceName);

builder.Logging.AddOpenTelemetry(options =>
{
    options
        .SetResourceBuilder(resourceBuilder)
        .AddConsoleExporter()
        .AddOtlpExporter(opt =>
        {
            // 配置OTLP端点指向日志存储的OTLP入口(如Loki或OpenTelemetry Collector)
            opt.Endpoint = new Uri("http://your-log-storage-otlp-endpoint:4317");
        });
    // 开启日志上下文与追踪关联
    options.IncludeScopes = true;
    options.ParseStateValues = true;
    options.IncludeFormattedMessage = true;
    // 手动注入Trace ID和Span ID到日志属性
    options.EnrichWithScope((logRecord, scope) =>
    {
        if (Activity.Current != null)
        {
            logRecord.Attributes["trace_id"] = Activity.Current.TraceId.ToString();
            logRecord.Attributes["span_id"] = Activity.Current.SpanId.ToString();
        }
    });
});

// 若直接使用Loki Exporter,可替换为以下配置(可选)
// builder.Logging.AddLoki(options =>
// {
//     options.Uri = new Uri("http://your-loki-instance:3100");
//     options.LabelProvider = (logLevel, categoryName) => new List<LokiLabel>
//     {
//         new LokiLabel("service", DiagnosticsConfig.ServiceName),
//         new LokiLabel("trace_id", Activity.Current?.TraceId.ToString() ?? string.Empty),
//         new LokiLabel("span_id", Activity.Current?.SpanId.ToString() ?? string.Empty)
//     };
// });

3. 校验OTLP配置一致性

确保日志的OTLP导出配置(端点、协议、认证信息等)和追踪的OTLP配置完全一致。如果使用OpenTelemetry Collector作为中转,需配置Collector同时接收追踪和日志数据,分别转发到Tempo和日志存储系统。

4. 验证日志级别设置

检查appsettings.json中的日志级别,确保能覆盖你输出的所有日志等级:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "YourAppNamespace": "Trace" // 替换为你的项目命名空间,确保能捕获Trace/Debug级日志
    }
  }
}

5. 在Grafana中关联日志与追踪

配置Grafana的Loki(或其他日志存储)数据源后,在Tempo explorer中查看追踪时,可通过Trace ID跳转到对应日志;也可在Loki查询中通过{trace_id="目标TraceID"}检索关联的日志内容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:47:08