dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.15k stars 4.71k forks source link

[API Proposal]: Allow to delete an instrument inside a Meter instance #83822

Open LGouellec opened 1 year ago

LGouellec commented 1 year ago

Background and motivation

For now, when you create an instance of Meter you can create multiple types of instrument (Histogram, Counter, ObservableGauge or ObservableCounter).

But you can't delete one observable gauge (for instance) previously created. The only way is to dispose the Meter instance and recreate from scratch with all instruments minus the instrument supposed to remove. It's not efficient at all.

API Proposal


 public class Meter : IDisposable
{
       private List<Instrument> _instruments = new List<Instrument>();
       // ....

      public void Remove(Instrument instrument) {
           _instruments.Remove(instrument)
     }
}

API Usage

var meter = new Meter("ServiceName");
var gauge =  meter.CreateObservableGauge(
                        key, 
                        () => new[]
                        {
                            new Measurement<double>(
                                value,
                                tags)
                        },
                        description: summary);           

meter.Remove(gauge);

Alternative Designs

No response

Risks

No response

tommcdon commented 1 year ago

@noahfalk @tarekgh

asasine commented 1 year ago

I would think that having Instrument implement IDisposable is the canonical way to indicate that instruments are disposable. Stealing from the Observer design pattern, the instances of Instrument can hold references to their Meter and remove themself from the meter's collection when disposed. This further supports the DI model as types only need to depend on the appropriate instrument, not the meter, to accurately dispose of the instrument when the DI container disposes them.

LGouellec commented 1 month ago

Hey there,

Do you have any news on top of that matter ?

Best regards,

julealgon commented 1 month ago

@LGouellec could you elaborate what kinds of use cases this would be used with? I tend to agree with your proposal but I'm curious to understand what scenario you have that requires removing instruments dynamically like this.

LGouellec commented 1 month ago

@julealgon

I work on this open source project , a .Net Kafka Streams implementation. Typically, I need to expose couple of instruments based on a Kafka Partition and probably you know but the kafka partitions can be reassigned if you have more consumers in the loop, basically if you scale in or out the number of your applications.

So when the partition is reassigned, I need to drop the instrument in the app A to avoid incoherent monitoring.

Let me know, if you have any further questions.

BrannanKovachev commented 3 weeks ago

My team is also interested in such a feature. We would like our application to begin collecting specific metrics from a gauge given a condition. Then once the condition is no longer met, stop the instrument from reporting. It doesn't make sense to destroy the entire meter and re-register all the instruments.

The OpenTelemetery Metrics API docs describe this as a requirement (you can look at any of the asynchronous instruments).

julealgon commented 3 weeks ago

My team is also interested in such a feature.

@BrannanKovachev upvote the original post to signal that if you can.

tmakin commented 1 week ago

I've been exploring the new Meter features with a view to replacing the Prometheus.net exporter. The lack of remove/delete for expired instruments is currently a blocker for adoption, so I think this feature would be really useful. My use case is to track equipment with intermittent availability, when the source goes offline I don't want the old metrics hanging around. Tearing down the entire meter every few seconds seems like overkill, as there are some instruments that I don't want to drop.