Metrics
Metrics
Section titled “Metrics”All metric-related attributes live in the Purview.Telemetry namespace. To signal an interface for meter generation, decorate it with the [Meter] attribute.
When creating the meter types, the IMeterFactory is used when available (it is not available on .NET Framework 4.8, where a new Meter(...) is created instead).
Meter naming
Section titled “Meter naming”The meter name is resolved in this order:
MeterAttribute.Name(interface)MeterGenerationAttribute.MeterName(assembly)- The assembly name
[Meter("InventoryService")]interface IInventoryMetrics { }Instrument naming
Section titled “Instrument naming”An instrument name is built from up to four dot-separated parts, outermost first:
- The meter name - only with
[assembly: MeterGeneration(MeterNameGenerationType = MeterNameGenerationType.OpenTelemetry)]. The default,MeterNameGenerationType.DotNet, leaves it out: the meter already identifies its instruments. MeterGenerationAttribute.InstrumentPrefix(assembly), unlessMeterAttribute.IncludeAssemblyInstrumentPrefixisfalse.- The interface prefix:
MeterAttribute.InstrumentPrefixwhen set, otherwise derived from the interface name by removing the leadingIand a trailingTelemetryorLogs(IProductTelemetrybecomesproduct). - The instrument’s
Name, or the method name.
With the default NamingConvention.OpenTelemetry, word boundaries in every part become underscores (RecordCount becomes record_count, MyApp.Products becomes my_app.products); NamingConvention.Legacy only lowercases them. LowercaseInstrumentName = false keeps every part as written.
[Meter("MyApp.Products")]interface IProductTelemetry{ [Counter] void RecordCount([InstrumentMeasurement] int count);}| Configuration | Instrument name |
|---|---|
| Defaults | product.record_count |
MeterNameGenerationType.OpenTelemetry | my_app.products.product.record_count |
NamingConvention.Legacy | product.recordcount |
These three names are pinned by the Generate_GivenTheDocumentedExample* tests in TelemetrySourceGeneratorMetricsTests.MeterNaming.cs.
MeterNameGenerationType.OpenTelemetry also lowercases a meter name that falls back to the assembly name.
Initialisation
Section titled “Initialisation”During initialisation you can implement a partial method to provide additional tags to any meters created by the IMeterFactory:
partial void PopulateMeterTags(System.Collections.Generic.Dictionary<string, object?> meterTags){ meterTags["environment"] = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");}Any tags added to meterTags are included on every meter created.
Instrument types
Section titled “Instrument types”Each instrument is determined by its corresponding attribute:
[AutoCounter]and[Counter]generate theCounter<T>instrument.[Histogram]generates theHistogram<T>instrument.[UpDownCounter]generates theUpDownCounter<T>instrument.[ObservableCounter]generates theObservableCounter<T>instrument.[ObservableGauge]generates theObservableGauge<T>instrument.[ObservableUpDownCounter]generates theObservableUpDownCounter<T>instrument.
The measurement type must be one of byte, short, int, long, float, double, or decimal.
The measurement value
Section titled “The measurement value”The measurement parameter is the parameter decorated with [InstrumentMeasurement]. For non-auto-increment instruments, if no parameter is decorated the first parameter with a valid measurement type that is not a [Tag]/[Baggage] is used.
[AutoCounter]and[Counter(AutoIncrement = true)]increment by 1 each time the method is called and must not declare a measurement parameter (TSG4002).[Counter],[Histogram], and[UpDownCounter]require a measurement value (TSG4004).- Observable instruments must declare a
Func<T>parameter (TSG4005).
[Meter]interface IMeterTelemetry{ [AutoCounter] void AutoIncrementMeter([Tag]string someValue);
[Counter(AutoIncrement = true)] void AutoIncrementCounterMeter([Tag]string someValue);
[Counter] void CounterMeter([InstrumentMeasurement]int measurement, [Tag]float someValue);
[Histogram] void HistogramMeter([InstrumentMeasurement]int measurement, [Tag]int someValue, [Tag]bool anotherValue);
[UpDownCounter] void UpDownCounterMeter([InstrumentMeasurement]decimal measurement, [Tag]byte someValue);}Observable instruments
Section titled “Observable instruments”Observable instruments always take a System.Func<> parameter with one of the following shapes:
- Any supported measurement type:
byte,short,int,long,float,double, ordecimal Measurement<T>whereTis a supported measurement typeIEnumerable<Measurement<T>>whereTis a supported measurement type
[ObservableCounter]void Counter(Func<int> func);
[ObservableGauge]void Gauge(Func<Measurement<int>> func);
[ObservableUpDownCounter]void UpDownCounter(Func<IEnumerable<Measurement<int>>> func);Other parameters on the method are used as tags. This is implicit for non-measurement parameters, but can also be made explicit with [Tag]. When there are four or more tags, the generated code uses a stack-allocated TagList.
Attribute reference
Section titled “Attribute reference”[Meter]
Section titled “[Meter]”Defines and controls the generation of meters and instruments on an interface, overriding assembly-level defaults.
| Property | Type | Description |
|---|---|---|
Name | string? | The name of the meter, used to group instruments. If not specified, MeterGenerationAttribute.MeterName is used, then the assembly name. Default null. |
InstrumentPrefix | string? | The prefix used when generating instrument names. Default null. |
IncludeAssemblyInstrumentPrefix | bool | Whether the MeterGenerationAttribute.InstrumentPrefix prefix is included in instrument names. Default true. |
LowercaseInstrumentName | bool | Whether instrument names (including prefix) are lower-cased. Default true. |
LowercaseTagKeys | bool | Whether tag names are lower-cased. Default true. |
[MeterGeneration]
Section titled “[MeterGeneration]”Controls meter and instrument defaults at the assembly level.
| Property | Type | Description |
|---|---|---|
MeterName | string? | The default meter name when none is defined on an interface. Available on construction. |
MeterNameGenerationType | MeterNameGenerationType | Whether the meter name is used as a dot-separated prefix for instrument names. OpenTelemetry (0) adds the prefix; DotNet (1, default) does not. Available on construction. |
InstrumentPrefix | string? | The prefix used when generating instrument names. Default null. |
InstrumentSeparator | string | The separator used when generating prefixes. Default .. |
LowercaseInstrumentName | bool | Whether instrument names (including prefix) are lower-cased. Default true. |
LowercaseTagKeys | bool | Whether tag names are lower-cased. Default true. |
[InstrumentMeasurement]
Section titled “[InstrumentMeasurement]”Marks the parameter used as the instrument measurement value. Not supported with [AutoCounter] or [Counter(AutoIncrement = true)].
Instrument attributes
Section titled “Instrument attributes”[AutoCounter]
Section titled “[AutoCounter]”Creates a Counter<int> that increments by 1 per call.
| Property | Type | Description |
|---|---|---|
Name | string? | Instrument name; defaults to the method name. Available on construction. Default null. |
Unit | string? | The unit used during meter generation. Available on construction. Default null. |
Description | string? | The description used during meter generation. Available on construction. Default null. |
[Counter]
Section titled “[Counter]”Creates a Counter<T>.
| Property | Type | Description |
|---|---|---|
AutoIncrement | bool | When true, generates an auto-incrementing counter instead of accepting a measurement value from a parameter. Available on construction. Default false. |
Name | string? | Instrument name; defaults to the method name. Available on construction. Default null. |
Unit | string? | The unit used during meter generation. Available on construction. Default null. |
Description | string? | The description used during meter generation. Available on construction. Default null. |
When AutoIncrement is true and [InstrumentMeasurement] is used, the TSG4002 diagnostic is raised.
[Histogram] and [UpDownCounter]
Section titled “[Histogram] and [UpDownCounter]”Create a Histogram<T> or UpDownCounter<T>. Both share the Name, Unit, and Description properties described above.
Observable attributes
Section titled “Observable attributes”[ObservableCounter], [ObservableGauge], and [ObservableUpDownCounter] share the Name, Unit, and Description properties, plus:
| Property | Type | Description |
|---|---|---|
ThrowOnAlreadyInitialized | bool | Whether the method throws when called more than once. Available on construction. Default false. |
Next steps
Section titled “Next steps”- Tags, Baggage, and Parameter Attributes — tagging parameters
- Multi-Targeting — combining Metrics with Activities and Logging
- Diagnostics — the
TSG4xxxMetrics rules