Add view (configuration only)#2396
Conversation
| { | ||
| using var meterProvider = Sdk.CreateMeterProviderBuilder() | ||
| .AddSource(MyMeter.Name) | ||
| .AddView(instrumentName: "MyCounter") // MyCounter will be reported with defaults. This is done to ensure that any other wildcard Views for the same isntrument does not affect this instrument. |
There was a problem hiding this comment.
my gut says, unless one understands View's concept from the spec (and concept of metric stream), this is not super intuitive. :)
There was a problem hiding this comment.
I see you have a class for MetricStreamConfig. How about a class for SelectionCriteria as well?
So the signature would be AddView(SelectionCriteria, MetricStreamConfig).
Later we might consider some builder methods for these classes as well. Something like:
var selectionCriteria = SelectionCriteria
.Create()
.MeterName("SomeMeter")
.InstrumentName("SomeInstrument");
var viewConfig = MetricStreamConfig
.Create()
.Name("NewNameForSomeMeter")
.Aggregation(Aggregation.Histogram);There was a problem hiding this comment.
MetricStreamConfig is internal (my bad missed removing it from public!).
User doesn't see that.
| selectInstrument &= true; | ||
| } | ||
|
|
||
| if (!string.IsNullOrWhiteSpace(meterVersion) |
There was a problem hiding this comment.
if selectInstrument is already true these checks can be skipped
There was a problem hiding this comment.
Since these 3 string are already checked for IsNullOrWhiteSpace should we cache that value? Or can we indicate to the compiler this string will never change, make them in arguments? https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier
| incomingInstrumentType = InstrumentType.Histogram; | ||
| } | ||
|
|
||
| if (incomingInstrumentType == instrumentType) |
There was a problem hiding this comment.
Could this be the body of an else statement
mic-max
left a comment
There was a problem hiding this comment.
I think the end user experience is good. I think I understood at least how to set things up. The wildcard part and having to put certain views above that one could be an issue I see people running into if they're not very conscious of that, especially when those strings might not be literals and be loaded from a less visible config or environment variable.
Codecov Report
@@ Coverage Diff @@
## main #2396 +/- ##
==========================================
- Coverage 80.19% 79.95% -0.24%
==========================================
Files 235 237 +2
Lines 7569 7599 +30
==========================================
+ Hits 6070 6076 +6
- Misses 1499 1523 +24
|
|
From offline discussions with @alanwest
|
| { | ||
| using var meterProvider = Sdk.CreateMeterProviderBuilder() | ||
| .AddSource(MyMeter.Name) | ||
| .AddView(instrumentName: "MyCounter") // MyCounter will be reported with defaults. This is done to ensure that any other wildcard Views for the same instrument does not affect this instrument. |
There was a problem hiding this comment.
minor, these lines are too long, consider making them block comments, e.g.:
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddSource(MyMeter.Name)
/* MyCounter will be reported with defaults.
This is done to ensure that any other wildcard Views for
the same instrument does not affect this instrument. */
.AddView(instrumentName: "MyCounter") There was a problem hiding this comment.
Agree.
Also I plan to move most of these comments to the readme, to make the program cleaner.
A readme section showing View examples should be very useful.
| using System.Collections.Generic; | ||
| using System.Text; | ||
|
|
||
| namespace OpenTelemetry.Metrics |
There was a problem hiding this comment.
Let's have offline discussion, I think a hierarchical design might help us to clean this up.
| .AddView((instrument) => | ||
| { | ||
| if (instrument.Meter.Name.Equals("CompanyA.ProductB.Library2") && | ||
| instrument.GetType().Name.StartsWith("Histogram")) |
There was a problem hiding this comment.
might benefit from some extension method like instrument.IsHistogram?
There was a problem hiding this comment.
I like this idea - fine as a follow up probably.
Maybe something like instrument.InstrumentType that returns an enum'ed value.
| .AddView(instrumentName: "MyCounterCustomTags", new AggregationConfig() { TagKeys = new string[] { "tag1", "tag2" } }) | ||
|
|
||
| // Drop the instrument "MyCounterDrop". | ||
| .AddView(instrumentName: "MyCounterDrop", new DropAggregationConfig()) |
There was a problem hiding this comment.
This is a bit weird.
Consider something like new AggregationConfig { Type = None }?
There was a problem hiding this comment.
Looks like this got commented out for now, I do like new AggregationConfig { Type = None }. Another idea is having some static AggregationConfigs for common scenarios like
class AggregationConfig
{
static AggregationConfig None = new AggregationConfig() { Aggregation = Aggregation.None };
}Hmm, maybe nevermind because then people could mutate the static configs.
There was a problem hiding this comment.
yes, this is something which can potentially be improved.
| .AddView(instrumentName: "MyCounter", name: "MyCounterRenamed") | ||
|
|
||
| // Change Histogram bounds | ||
| .AddView(instrumentName: "MyHistogram", new HistogramConfig() { HistogramBounds = new double[] { 10, 20 } }) |
There was a problem hiding this comment.
| .AddView(instrumentName: "MyHistogram", new HistogramConfig() { HistogramBounds = new double[] { 10, 20 } }) | |
| .AddView(instrumentName: "MyHistogram", new HistogramConfiguration { BucketBounds = new { 10, 20 } }) |
There was a problem hiding this comment.
I don't know which one is better HistogramBounds, BucketBounds or just Bounds. HistogramBounds seems to be bad because the type already suggested that it is Histogram.
alanwest
left a comment
There was a problem hiding this comment.
Put a few thoughts, but this is looking 👍
## Changes Update the compliance matrix for .NET as of 1.16.0 of the .NET SDK. I got Copilot to do most of the work of researching what was missing that had been implementing and finding the relevant PRs that implemented then. I cross checked the PRs _looked_ correct, but some of it might be incorrect, particularly things that seem to have been implemented for a while and predate my contributions to OTel. I then had Claude review the changes and cross-reference, which fixed some of the entries, but again there might still be some mistakes. ~~Some of the entries might only be available as experimental features, so maybe they shouldn't be updated?~~ Experimental entries removed, now marked as ~~strikethrough~~ below. Entries updated with relevant PR links where appropriate below. /cc @open-telemetry/dotnet-maintainers ### Traces - Get a Tracer with schema_url: open-telemetry/opentelemetry-dotnet#6736 - Get a Tracer with scope attributes: open-telemetry/opentelemetry-dotnet#6137 - Associate Tracer with InstrumentationScope: open-telemetry/opentelemetry-dotnet#239 - Fetch InstrumentationScope from ReadableSpan: open-telemetry/opentelemetry-dotnet#679 ### Metrics - Associate Meter with InstrumentationScope: open-telemetry/opentelemetry-dotnet#6714 - Gauge instrument is supported: open-telemetry/opentelemetry-dotnet#5867 - Valid instrument created / warning for duplicate name: open-telemetry/opentelemetry-dotnet#2916 - Duplicate instrument registration resolved by first-seen: open-telemetry/opentelemetry-dotnet#2916 - Instrument names conform to specified syntax: open-telemetry/opentelemetry-dotnet#3821 - Instrument supports advisory ExplicitBucketBoundaries: open-telemetry/opentelemetry-dotnet#5854 - Instrument supports advisory Attributes: Not implemented - name/version/schema_url create InstrumentationScope: open-telemetry/opentelemetry-dotnet#6714 - ~~View allows configuring name, description, attributes, aggregation: open-telemetry/opentelemetry-dotnet#2396 - ~~View allows configuring exemplar reservoir: open-telemetry/opentelemetry-dotnet#5558 - Metrics Reader supports default aggregation config: open-telemetry/opentelemetry-dotnet#6778 - Metrics Reader supports default temporality config: open-telemetry/opentelemetry-dotnet#4667 - ~~ExemplarReservoir interface/extension point: open-telemetry/opentelemetry-dotnet#5542 - ~~ExemplarReservoir has offer method: open-telemetry/opentelemetry-dotnet#5542 - SimpleFixedSizeExemplarReservoir: open-telemetry/opentelemetry-dotnet#4256 - AlignedHistogramBucketExemplarReservoir: open-telemetry/opentelemetry-dotnet#4119 ### Logs - ~~LoggerProvider.GetLogger: open-telemetry/opentelemetry-dotnet#4422 - LoggerProvider.GetLogger accepts attributes: Not implemented - LoggerProvider.Shutdown: open-telemetry/opentelemetry-dotnet#5648 - LoggerProvider.ForceFlush: open-telemetry/opentelemetry-dotnet#5648 - Logger.Emit(LogRecord) with Exception parameter: Not implemented - ~~LogRecord.Set EventName: open-telemetry/opentelemetry-dotnet#6306 - Logger.Enabled: Not implemented - Ergonomic API (ILogger bridge): open-telemetry/opentelemetry-dotnet#3489 - SimpleLogRecordProcessor: open-telemetry/opentelemetry-dotnet#1622 - BatchLogRecordProcessor: open-telemetry/opentelemetry-dotnet#1622 - Can plug custom LogRecordProcessor: open-telemetry/opentelemetry-dotnet#4916 - LogRecordProcessor.Enabled: Not implemented - Can plug custom LogRecordExporter: open-telemetry/opentelemetry-dotnet#1622 ### Context Propagation - Jaeger Propagator: open-telemetry/opentelemetry-dotnet#3309 - TextMapPropagator: open-telemetry/opentelemetry-dotnet#1427 ### Environment Variables - OTEL_SDK_DISABLED: open-telemetry/opentelemetry-dotnet#6568 - OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT: open-telemetry/opentelemetry-dotnet#4887 - OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT: open-telemetry/opentelemetry-dotnet#4887 - OTEL_TRACES_SAMPLER: open-telemetry/opentelemetry-dotnet#5448 - OTEL_TRACES_SAMPLER_ARG: open-telemetry/opentelemetry-dotnet#5448 - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION: open-telemetry/opentelemetry-dotnet#6778 ### Exporters — OTLP - OTLP/HTTP gzip Content-Encoding support: open-telemetry/opentelemetry-dotnet#7055 - ~~Honors retryable responses with backoff: open-telemetry/opentelemetry-dotnet#5495 - ~~Honors non-retryable responses: open-telemetry/opentelemetry-dotnet#5495 - ~~Honors throttling response: open-telemetry/opentelemetry-dotnet#5495 - Metric Exporter configurable temporality preference: open-telemetry/opentelemetry-dotnet#4667 - Metric Exporter configurable default aggregation: open-telemetry/opentelemetry-dotnet#6778 ### Exporters — Zipkin - InstrumentationScope mapping: open-telemetry/opentelemetry-dotnet#5473 ### Exporters — Prometheus - Metadata Deduplication: open-telemetry/opentelemetry-dotnet#7237 - otel_scope_name and otel_scope_version labels: open-telemetry/opentelemetry-dotnet#7237 - otel_scope_[attribute] labels: open-telemetry/opentelemetry-dotnet#7237 - Prometheus Counters have _total suffix by default: open-telemetry/opentelemetry-dotnet#5305 - Prometheus Counters _total suffixing can be disabled: open-telemetry/opentelemetry-dotnet#5305 - Colliding sanitized attribute keys are merged: open-telemetry/opentelemetry-dotnet#7239 - Exemplars for Histograms and Monotonic sums: open-telemetry/opentelemetry-dotnet#7222 - target_info metric from Resource: open-telemetry/opentelemetry-dotnet#5407 ### OpenTracing Compatibility - Create OpenTracing Shim: open-telemetry/opentelemetry-dotnet#197 - Tracer shim: open-telemetry/opentelemetry-dotnet#197 - Span shim: open-telemetry/opentelemetry-dotnet#197 - SpanContext shim: open-telemetry/opentelemetry-dotnet#197 - ScopeManager shim: open-telemetry/opentelemetry-dotnet#197 - Error mapping for attributes/events: open-telemetry/opentelemetry-dotnet#197
Adds ability to add Views.
Documents/example.
In next PRs: Actual implementation.