# System.Diagnostics.Metrics

``` diff
+namespace System.Diagnostics.Metrics {
+    public sealed class Counter<T> : Instrument<T> where T : struct {
+        public void Add(T delta);
+        public void Add(T delta, KeyValuePair<string, object> tag);
+        public void Add(T delta, KeyValuePair<string, object> tag1, KeyValuePair<string, object> tag2);
+        public void Add(T delta, KeyValuePair<string, object> tag1, KeyValuePair<string, object> tag2, KeyValuePair<string, object> tag3);
+        public void Add(T delta, params KeyValuePair<string, object>[] tags);
+        public void Add(T delta, in TagList tagList);
+        public void Add(T delta, ReadOnlySpan<KeyValuePair<string, object>> tags);
+    }
+    public sealed class Histogram<T> : Instrument<T> where T : struct {
+        public void Record(T value);
+        public void Record(T value, KeyValuePair<string, object> tag);
+        public void Record(T value, KeyValuePair<string, object> tag1, KeyValuePair<string, object> tag2);
+        public void Record(T value, KeyValuePair<string, object> tag1, KeyValuePair<string, object> tag2, KeyValuePair<string, object> tag3);
+        public void Record(T value, params KeyValuePair<string, object>[] tags);
+        public void Record(T value, in TagList tagList);
+        public void Record(T value, ReadOnlySpan<KeyValuePair<string, object>> tags);
+    }
+    public abstract class Instrument {
+        protected Instrument(Meter meter, string name, string unit, string description);
+        public string Description { get; }
+        public bool Enabled { get; }
+        public virtual bool IsObservable { get; }
+        public Meter Meter { get; }
+        public string Name { get; }
+        public string Unit { get; }
+        protected void Publish();
+    }
+    public abstract class Instrument<T> : Instrument where T : struct {
+        protected Instrument(Meter meter, string name, string unit, string description);
+        protected void RecordMeasurement(T measurement);
+        protected void RecordMeasurement(T measurement, KeyValuePair<string, object> tag);
+        protected void RecordMeasurement(T measurement, KeyValuePair<string, object> tag1, KeyValuePair<string, object> tag2);
+        protected void RecordMeasurement(T measurement, KeyValuePair<string, object> tag1, KeyValuePair<string, object> tag2, KeyValuePair<string, object> tag3);
+        protected void RecordMeasurement(T measurement, in TagList tagList);
+        protected void RecordMeasurement(T measurement, ReadOnlySpan<KeyValuePair<string, object>> tags);
+    }
+    public readonly struct Measurement<T> where T : struct {
+        public Measurement(T value);
+        public Measurement(T value, IEnumerable<KeyValuePair<string, object>> tags);
+        public Measurement(T value, params KeyValuePair<string, object>[] tags);
+        public Measurement(T value, ReadOnlySpan<KeyValuePair<string, object>> tags);
+        public ReadOnlySpan<KeyValuePair<string, object>> Tags { get; }
+        public T Value { get; }
+    }
+    public delegate void MeasurementCallback<T>(Instrument instrument, T measurement, ReadOnlySpan<KeyValuePair<string, object>> tags, object state);
+    public class Meter : IDisposable {
+        public Meter(string name);
+        public Meter(string name, string version);
+        public string Name { get; }
+        public string Version { get; }
+        public Counter<T> CreateCounter<T>(string name, string unit = null, string description = null) where T : struct;
+        public Histogram<T> CreateHistogram<T>(string name, string unit = null, string description = null) where T : struct;
+        public ObservableCounter<T> CreateObservableCounter<T>(string name, Func<IEnumerable<Measurement<T>>> observeValues, string unit = null, string description = null) where T : struct;
+        public ObservableCounter<T> CreateObservableCounter<T>(string name, Func<Measurement<T>> observeValue, string unit = null, string description = null) where T : struct;
+        public ObservableCounter<T> CreateObservableCounter<T>(string name, Func<T> observeValue, string unit = null, string description = null) where T : struct;
+        public ObservableGauge<T> CreateObservableGauge<T>(string name, Func<IEnumerable<Measurement<T>>> observeValues, string unit = null, string description = null) where T : struct;
+        public ObservableGauge<T> CreateObservableGauge<T>(string name, Func<Measurement<T>> observeValue, string unit = null, string description = null) where T : struct;
+        public ObservableGauge<T> CreateObservableGauge<T>(string name, Func<T> observeValue, string unit = null, string description = null) where T : struct;
+        public void Dispose();
+    }
+    public sealed class MeterListener : IDisposable {
+        public MeterListener();
+        public Action<Instrument, MeterListener> InstrumentPublished { get; set; }
+        public Action<Instrument, object> MeasurementsCompleted { get; set; }
+        public object DisableMeasurementEvents(Instrument instrument);
+        public void Dispose();
+        public void EnableMeasurementEvents(Instrument instrument, object state = null);
+        public void RecordObservableInstruments();
+        public void SetMeasurementEventCallback<T>(MeasurementCallback<T> measurementCallback) where T : struct;
+        public void Start();
+    }
+    public sealed class ObservableCounter<T> : ObservableInstrument<T> where T : struct {
+        protected override IEnumerable<Measurement<T>> Observe();
+    }
+    public sealed class ObservableGauge<T> : ObservableInstrument<T> where T : struct {
+        protected override IEnumerable<Measurement<T>> Observe();
+    }
+    public abstract class ObservableInstrument<T> : Instrument where T : struct {
+        protected ObservableInstrument(Meter meter, string name, string unit, string description);
+        public override bool IsObservable { get; }
+        protected abstract IEnumerable<Measurement<T>> Observe();
+    }
+}
```

