Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Counter generated from System.Diagnostic.Metrics resets to zero. #103670

Closed
bthharper opened this issue Jun 15, 2024 · 3 comments
Closed

Counter generated from System.Diagnostic.Metrics resets to zero. #103670

bthharper opened this issue Jun 15, 2024 · 3 comments

Comments

@bthharper
Copy link

Description

The counters in .NET 8 (or .NET 4.8) reset to zero whilst running, losing the current measurement.

Reproduction Steps

Run the following code sample in Rider (or on the command line) ..

using System.Diagnostics.Metrics;

Console.WriteLine("Hello, World!");

using var meter = new Meter("Metrics", "1.0.0");

var counter1 = meter.CreateCounter<long>("1.count");
var counter2 = meter.CreateCounter<long>("2.count");
var counter3 = meter.CreateCounter<long>("3.count");
var counter4 = meter.CreateCounter<long>("4.count");

using var meterListener = new MeterListener();

meterListener.SetMeasurementEventCallback<long>(ShowMeasurement);
meterListener.EnableMeasurementEvents(counter1);
meterListener.EnableMeasurementEvents(counter2);
meterListener.EnableMeasurementEvents(counter3);
meterListener.EnableMeasurementEvents(counter4);

var rnd = Random.Shared;
while (true) {
    Thread.Sleep(TimeSpan.FromSeconds(rnd.Next(0, 5)));
    switch (rnd.Next(0, 4)) {
        case 0:
            counter1.Add(1);
            break;
        case 1:
            counter2.Add(1);
            break;
        case 2:
            counter3.Add(1);
            break;
        case 3:
            counter4.Add(1);
            break;
    }
}

static void ShowMeasurement<T>(
    Instrument instrument,
    T measurement,
    ReadOnlySpan<KeyValuePair<string, object>> tags,
    object state) {
    Console.WriteLine($"{instrument.Name} = {measurement}");
}

Expected behavior

The counters to increment until the application is stopped.

Actual behavior

image

image

Regression?

No response

Known Workarounds

No response

Configuration

.NET 8 (8.0.5) and .NET 4.8.1
Windows 11 (latest)
x64

Other information

No response

@bthharper bthharper added the bug label Jun 15, 2024
@tommcdon tommcdon transferred this issue from dotnet/diagnostics Jun 18, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jun 18, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Jun 18, 2024
@vcsjones vcsjones removed the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jun 20, 2024
@tarekgh
Copy link
Member

tarekgh commented Jun 20, 2024

This is not how the metrics work in .NET. It is the listener/aggregator job to accumulate the published counter values. I encourage you to read the doc https://learn.microsoft.com/en-us/dotnet/core/diagnostics/metrics-collection#create-a-custom-collection-tool-using-the-net-meterlistener-api for more info and explanation.

@tarekgh tarekgh closed this as completed Jun 20, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Jun 20, 2024
@julealgon
Copy link

It is the listener/aggregator job to accumulate the published counter values.

@tarekgh do you mind if I ask a related question to this? I've never found proper documentation about it.

In a setup with an OTEL collector and an observability tool (e.g. Datadog), who exactly is performing this aggregation? Is it the application itself before emitting the values to the collector? Is it the collector? Or does the collector also sends raw values and they are aggregated by Datadog?

This has always confused me because it is not clear to me when a counter is supposed to reset, and how one even signals an intended reset (if that is even possible). Does a reset happen when I restart my application? Is there some sort of signal that is sent from the application side to indicate a counter is "a new instance" or "a new stream of deltas separate from previous ones", or is that defined by the collector or the observability tool?

Since counters are delta based, one would need to accumulate their values forever to have an accurate view: basically going back to the very first measurement. For example, imagine I wanted to track "hats sold throughout history", and my application has been running for 10 years. Do telemetry counters (or any other instruments really) work at that scale, or are they not meant to capture "persistent" telemetry like this?

I probably just missed it, but I couldn't find the answer for this "delta instrument aggregation lifetime" question in either the Microsoft docs, OTEL docs or even Datadog docs.

@tarekgh
Copy link
Member

tarekgh commented Jun 21, 2024

do you mind if I ask a related question to this?

You are welcome to ask any question anytime.

There is a good doc https://github.com/open-telemetry/opentelemetry-dotnet/tree/4af3df9b81dbf78f3abbbd5d764573db8d54d373/docs/metrics#meterprovider-management describing how metrics work in OpenTelelmetry. Please have a look and let's know if you still have any questions not answered.

CC @reyang @CodeBlanch @noahfalk

@github-actions github-actions bot locked and limited conversation to collaborators Jul 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants