Skip to content

Commit

Permalink
Add support for multiple readers (#2596)
Browse files Browse the repository at this point in the history
  • Loading branch information
utpilla authored Nov 19, 2021
1 parent 03313e7 commit ca29142
Show file tree
Hide file tree
Showing 12 changed files with 719 additions and 243 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ static OpenTelemetry.Metrics.MetricTypeExtensions.IsGauge(this OpenTelemetry.Met
static OpenTelemetry.Metrics.MetricTypeExtensions.IsHistogram(this OpenTelemetry.Metrics.MetricType self) -> bool
static OpenTelemetry.Metrics.MetricTypeExtensions.IsLong(this OpenTelemetry.Metrics.MetricType self) -> bool
static OpenTelemetry.Metrics.MetricTypeExtensions.IsSum(this OpenTelemetry.Metrics.MetricType self) -> bool
static OpenTelemetry.ProviderExtensions.GetMetricCollect(this OpenTelemetry.BaseProvider baseProvider) -> System.Func<OpenTelemetry.Batch<OpenTelemetry.Metrics.Metric>>
static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder
static readonly OpenTelemetry.Metrics.MetricStreamConfiguration.Drop -> OpenTelemetry.Metrics.MetricStreamConfiguration
virtual OpenTelemetry.BaseExporter<T>.OnForceFlush(int timeoutMilliseconds) -> bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ static OpenTelemetry.Metrics.MetricTypeExtensions.IsGauge(this OpenTelemetry.Met
static OpenTelemetry.Metrics.MetricTypeExtensions.IsHistogram(this OpenTelemetry.Metrics.MetricType self) -> bool
static OpenTelemetry.Metrics.MetricTypeExtensions.IsLong(this OpenTelemetry.Metrics.MetricType self) -> bool
static OpenTelemetry.Metrics.MetricTypeExtensions.IsSum(this OpenTelemetry.Metrics.MetricType self) -> bool
static OpenTelemetry.ProviderExtensions.GetMetricCollect(this OpenTelemetry.BaseProvider baseProvider) -> System.Func<OpenTelemetry.Batch<OpenTelemetry.Metrics.Metric>>
static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder
static readonly OpenTelemetry.Metrics.MetricStreamConfiguration.Drop -> OpenTelemetry.Metrics.MetricStreamConfiguration
virtual OpenTelemetry.BaseExporter<T>.OnForceFlush(int timeoutMilliseconds) -> bool
Expand Down
61 changes: 34 additions & 27 deletions src/OpenTelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,33 @@
([#2542](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2542))

* Added wildcard support for AddMeter.
([#2459](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2459))
([#2459](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2459))

* Add support for multiple Metric readers
([#2596](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2596))

## 1.2.0-beta1

Released 2021-Oct-08

* Exception from Observable instrument callbacks does not
result in entire metrics being lost.
* Exception from Observable instrument callbacks does not result in entire
metrics being lost.

* SDK is allocation-free on recording of measurements with
upto 8 tags.
* SDK is allocation-free on recording of measurements with upto 8 tags.

* TracerProviderBuilder.AddLegacySource now supports wildcard activity names.
([#2183](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2183))

* Instrument and View names are validated
[according with the spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument).
* Instrument and View names are validated [according with the
spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument).
([#2470](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2470))

## 1.2.0-alpha4

Released 2021-Sep-23

* `BatchExportProcessor.OnShutdown` will now log the count of dropped telemetry items.
* `BatchExportProcessor.OnShutdown` will now log the count of dropped telemetry
items.
([#2331](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2331))
* Changed `CompositeProcessor<T>.OnForceFlush` to meet with the spec
requirement. Now the SDK will invoke `ForceFlush` on all registered
Expand All @@ -60,36 +63,39 @@ Released 2021-Sep-23

Released 2021-Sep-13

* Metrics perf improvements, bug fixes.
Replace MetricProcessor with MetricReader.
* Metrics perf improvements, bug fixes. Replace MetricProcessor with
MetricReader.
([#2306](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2306))

* Add `BatchExportActivityProcessorOptions` which supports field value overriding
using `OTEL_BSP_SCHEDULE_DELAY`, `OTEL_BSP_EXPORT_TIMEOUT`,
`OTEL_BSP_MAX_QUEUE_SIZE`, `OTEL_BSP_MAX_EXPORT_BATCH_SIZE`
envionmental variables as defined in the
* Add `BatchExportActivityProcessorOptions` which supports field value
overriding using `OTEL_BSP_SCHEDULE_DELAY`, `OTEL_BSP_EXPORT_TIMEOUT`,
`OTEL_BSP_MAX_QUEUE_SIZE`, `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` envionmental
variables as defined in the
[specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.5.0/specification/sdk-environment-variables.md#batch-span-processor).
([#2219](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2219))

## 1.2.0-alpha2

Released 2021-Aug-24

* More Metrics features. All instrument types, push/pull
exporters, Delta/Cumulative temporality supported.
* More Metrics features. All instrument types, push/pull exporters,
Delta/Cumulative temporality supported.

* `ResourceBuilder.CreateDefault` has detectors for
`OTEL_RESOURCE_ATTRIBUTES`, `OTEL_SERVICE_NAME` environment variables
so that explicit `AddEnvironmentVariableDetector` call is not needed. ([#2247](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2247))
* `ResourceBuilder.CreateDefault` has detectors for `OTEL_RESOURCE_ATTRIBUTES`,
`OTEL_SERVICE_NAME` environment variables so that explicit
`AddEnvironmentVariableDetector` call is not needed.
([#2247](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2247))

* `ResourceBuilder.AddEnvironmentVariableDetector` handles `OTEL_SERVICE_NAME`
environmental variable. ([#2209](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2209))
environmental variable.
([#2209](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2209))

* Removes upper constraint for Microsoft.Extensions.Logging
dependencies. ([#2179](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2179))
* Removes upper constraint for Microsoft.Extensions.Logging dependencies.
([#2179](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2179))

* OpenTelemetryLogger modified to not throw, when the
formatter supplied in ILogger.Log call is null. ([#2200](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2200))
* OpenTelemetryLogger modified to not throw, when the formatter supplied in
ILogger.Log call is null.
([#2200](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2200))

## 1.2.0-alpha1

Expand All @@ -100,7 +106,8 @@ Released 2021-Jul-23
([#2174](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2174))

* Removes .NET Framework 4.5.2, .NET 4.6 support. The minimum .NET Framework
version supported is .NET 4.6.1. ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2138))
version supported is .NET 4.6.1.
([#2138](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2138))

## 1.1.0

Expand Down Expand Up @@ -137,8 +144,8 @@ Released 2021-May-11
Released 2021-Apr-23

* Use `AssemblyFileVersionAttribute` instead of `FileVersionInfo.GetVersionInfo`
to get the SDK version attribute to ensure that it works when the assembly
is not loaded directly from a file on disk
to get the SDK version attribute to ensure that it works when the assembly is
not loaded directly from a file on disk
([#1908](https://github.com/open-telemetry/opentelemetry-dotnet/issues/1908))

## 1.1.0-beta1
Expand Down
8 changes: 7 additions & 1 deletion src/OpenTelemetry/Metrics/CompositeMetricReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@

namespace OpenTelemetry.Metrics
{
internal sealed class CompositeMetricReader : MetricReader
/// <summary>
/// CompositeMetricReader that does not deal with adding metrics and recording measurements.
/// </summary>
internal sealed partial class CompositeMetricReader : MetricReader
{
private readonly DoublyLinkedListNode head;
private DoublyLinkedListNode tail;
private bool disposed;
private int count;

public CompositeMetricReader(IEnumerable<MetricReader> readers)
{
Expand All @@ -40,6 +44,7 @@ public CompositeMetricReader(IEnumerable<MetricReader> readers)

this.head = new DoublyLinkedListNode(iter.Current);
this.tail = this.head;
this.count++;

while (iter.MoveNext())
{
Expand All @@ -57,6 +62,7 @@ public CompositeMetricReader AddReader(MetricReader reader)
};
this.tail.Next = node;
this.tail = node;
this.count++;

return this;
}
Expand Down
149 changes: 149 additions & 0 deletions src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// <copyright file="CompositeMetricReaderExt.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Metrics;

namespace OpenTelemetry.Metrics
{
/// <summary>
/// CompositeMetricReader that deals with adding metrics and recording measurements.
/// </summary>
internal sealed partial class CompositeMetricReader
{
internal List<Metric> AddMetricsWithNoViews(Instrument instrument)
{
var metrics = new List<Metric>(this.count);
for (var cur = this.head; cur != null; cur = cur.Next)
{
var metric = cur.Value.AddMetricWithNoViews(instrument);
metrics.Add(metric);
}

return metrics;
}

internal void RecordSingleStreamLongMeasurements(List<Metric> metrics, long value, ReadOnlySpan<KeyValuePair<string, object>> tags)
{
Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers.");

int index = 0;
for (var cur = this.head; cur != null; cur = cur.Next)
{
if (metrics[index] != null)
{
cur.Value.RecordSingleStreamLongMeasurement(metrics[index], value, tags);
}

index++;
}
}

internal void RecordSingleStreamDoubleMeasurements(List<Metric> metrics, double value, ReadOnlySpan<KeyValuePair<string, object>> tags)
{
Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers.");

int index = 0;
for (var cur = this.head; cur != null; cur = cur.Next)
{
if (metrics[index] != null)
{
cur.Value.RecordSingleStreamDoubleMeasurement(metrics[index], value, tags);
}

index++;
}
}

internal List<List<Metric>> AddMetricsSuperListWithViews(Instrument instrument, List<MetricStreamConfiguration> metricStreamConfigs)
{
var metricsSuperList = new List<List<Metric>>(this.count);
for (var cur = this.head; cur != null; cur = cur.Next)
{
var metrics = cur.Value.AddMetricsListWithViews(instrument, metricStreamConfigs);
metricsSuperList.Add(metrics);
}

return metricsSuperList;
}

internal void RecordLongMeasurements(List<List<Metric>> metricsSuperList, long value, ReadOnlySpan<KeyValuePair<string, object>> tags)
{
Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers.");

int index = 0;
for (var cur = this.head; cur != null; cur = cur.Next)
{
if (metricsSuperList[index].Count > 0)
{
cur.Value.RecordLongMeasurement(metricsSuperList[index], value, tags);
}

index++;
}
}

internal void RecordDoubleMeasurements(List<List<Metric>> metricsSuperList, double value, ReadOnlySpan<KeyValuePair<string, object>> tags)
{
Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers.");

int index = 0;
for (var cur = this.head; cur != null; cur = cur.Next)
{
if (metricsSuperList[index].Count > 0)
{
cur.Value.RecordDoubleMeasurement(metricsSuperList[index], value, tags);
}

index++;
}
}

internal void CompleteSingleStreamMeasurements(List<Metric> metrics)
{
Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers.");

int index = 0;
for (var cur = this.head; cur != null; cur = cur.Next)
{
if (metrics[index] != null)
{
cur.Value.CompleteSingleStreamMeasurement(metrics[index]);
}

index++;
}
}

internal void CompleteMesaurements(List<List<Metric>> metricsSuperList)
{
Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers.");

int index = 0;
for (var cur = this.head; cur != null; cur = cur.Next)
{
if (metricsSuperList[index].Count > 0)
{
cur.Value.CompleteMeasurement(metricsSuperList[index]);
}

index++;
}
}
}
}
5 changes: 0 additions & 5 deletions src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,6 @@ public override MeterProviderBuilder AddMeter(params string[] names)

internal MeterProviderBuilder AddReader(MetricReader reader)
{
if (this.MetricReaders.Count >= 1)
{
throw new InvalidOperationException("Only one Metricreader is allowed.");
}

this.MetricReaders.Add(reader);
return this;
}
Expand Down
Loading

0 comments on commit ca29142

Please sign in to comment.