opentelemetry-dotnet icon indicating copy to clipboard operation
opentelemetry-dotnet copied to clipboard

Prometheus Http Listener missing tags

Open ricsiLT opened this issue 1 year ago • 1 comments

Bug Report

List of all OpenTelemetry NuGet packages and version that you are using (e.g. OpenTelemetry 1.0.2):

  • OpenTelemetry.Exporter.Prometheus.HttpListener (1.7.0-rc.1)
  • OpenTelemetry.Extensions.Hosting (1.7.0)

Runtime version (e.g. net462, net48, netcoreapp3.1, net6.0 etc. You can find this information from the *.csproj file):

  • net8

Symptom

Metric tags not present in http listener path.

What is the expected behavior?

Metric tagged with hostname.

What is the actual behavior?

Response from app on localhost:9464/metrics:

# TYPE custom_state gauge
# UNIT custom_state state
# HELP custom_state state of the application
custom_state 0 1702625390749

# EOF

Reproduce

Custom metrics class:

public class CustomMetrics
{
    private State _state;
    private readonly ObservableGauge<int> _stateGauge;

    public CustomMetrics(IMeterFactory meterFactory)
    {
        using var meter = meterFactory.Create("CustomMeter", "1.0.0");

        _stateGauge = meter.CreateObservableGauge<int>(
            "custom_state",
            () => (int)_state,
            "state",
            "state of the application",
            new List<KeyValuePair<string, object?>> { new("hostname", Environment.MachineName) }
        );
    }

    public void ChangeState(State newState) => _state = newState;
}

public enum State
{
    Idle,
    Working
}

Worker:

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private readonly CustomMetrics _customMetrics;

    public Worker(ILogger<Worker> logger, CustomMetrics customMetrics)
    {
        _logger = logger;
        _customMetrics = customMetrics;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Working");
            _customMetrics.ChangeState(State.Working);
            await Task.Delay(1000, stoppingToken);

            _logger.LogInformation("Idling");
            _customMetrics.ChangeState(State.Idle);
            await Task.Delay(1000, stoppingToken);
        }
    }
}

Program.cs:

var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();

builder.Services
    .AddSingleton<CustomMetrics>()
    .AddOpenTelemetry()
    .WithMetrics(providerBuilder => providerBuilder
        .AddMeter("CustomMeter")
        .AddPrometheusHttpListener()
    );

var host = builder.Build();
host.Run();

We will close this issue if:

  • The repro project you share with us is complex. We can't investigate custom projects, so don't point us to such, please.
  • If we can not reproduce the behavior you're reporting.

Additional Context

I see some similar issues in repo, just wasn't sure if this is exactly what is covered in them :(

ricsiLT avatar Dec 15 '23 07:12 ricsiLT

We are also facing a similar issue with the OpenTelemetry.Exporter.OpenTelemetry (Version 1.7.0) Exporter. The tags from an instrument are not exported to the OTEL collector. We have to add the tags to every measurement.

sprayzcs avatar Jan 08 '24 15:01 sprayzcs

For anyone who runs across this ticket, I ran into the same bug and Instrument-level metrics appears to be intentionally not supported because there isn't any such concept in the OpenTelemetry Specification. You can see comments about it here

james-newell-forge avatar Mar 13 '24 13:03 james-newell-forge

Closing as this is expected behavior today. (Not ruling out the possibility of supporting instrument level tags in the future)

cijothomas avatar Mar 13 '24 15:03 cijothomas