-
Notifications
You must be signed in to change notification settings - Fork 765
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[hosting] Support .NET 8 IMetricsBuilder API (#4958)
- Loading branch information
1 parent
0c4f065
commit 1f7f931
Showing
22 changed files
with
1,342 additions
and
639 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
src/OpenTelemetry.Extensions.Hosting/Implementation/OpenTelemetryMetricsListener.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// <copyright file="OpenTelemetryMetricsListener.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.Diagnostics; | ||
using System.Diagnostics.Metrics; | ||
using Microsoft.Extensions.Diagnostics.Metrics; | ||
|
||
namespace OpenTelemetry.Metrics; | ||
|
||
internal sealed class OpenTelemetryMetricsListener : IMetricsListener, IDisposable | ||
{ | ||
private readonly MeterProviderSdk meterProviderSdk; | ||
private IObservableInstrumentsSource? observableInstrumentsSource; | ||
|
||
public OpenTelemetryMetricsListener(MeterProvider meterProvider) | ||
{ | ||
var meterProviderSdk = meterProvider as MeterProviderSdk; | ||
|
||
Debug.Assert(meterProviderSdk != null, "meterProvider was not MeterProviderSdk"); | ||
|
||
this.meterProviderSdk = meterProviderSdk!; | ||
|
||
this.meterProviderSdk.OnCollectObservableInstruments += this.OnCollectObservableInstruments; | ||
} | ||
|
||
public string Name => "OpenTelemetry"; | ||
|
||
public void Dispose() | ||
{ | ||
this.meterProviderSdk.OnCollectObservableInstruments -= this.OnCollectObservableInstruments; | ||
} | ||
|
||
public MeasurementHandlers GetMeasurementHandlers() | ||
{ | ||
return new MeasurementHandlers() | ||
{ | ||
ByteHandler = (instrument, value, tags, state) | ||
=> this.MeasurementRecordedLong(instrument, value, tags, state), | ||
ShortHandler = (instrument, value, tags, state) | ||
=> this.MeasurementRecordedLong(instrument, value, tags, state), | ||
IntHandler = (instrument, value, tags, state) | ||
=> this.MeasurementRecordedLong(instrument, value, tags, state), | ||
LongHandler = this.MeasurementRecordedLong, | ||
FloatHandler = (instrument, value, tags, state) | ||
=> this.MeasurementRecordedDouble(instrument, value, tags, state), | ||
DoubleHandler = this.MeasurementRecordedDouble, | ||
}; | ||
} | ||
|
||
public bool InstrumentPublished(Instrument instrument, out object? userState) | ||
{ | ||
userState = this.meterProviderSdk.InstrumentPublished(instrument, listeningIsManagedExternally: true); | ||
return userState != null; | ||
} | ||
|
||
public void MeasurementsCompleted(Instrument instrument, object? userState) | ||
{ | ||
var meterProvider = this.meterProviderSdk; | ||
|
||
if (meterProvider.ViewCount > 0) | ||
{ | ||
meterProvider.MeasurementsCompleted(instrument, userState); | ||
} | ||
else | ||
{ | ||
meterProvider.MeasurementsCompletedSingleStream(instrument, userState); | ||
} | ||
} | ||
|
||
public void Initialize(IObservableInstrumentsSource source) | ||
{ | ||
this.observableInstrumentsSource = source; | ||
} | ||
|
||
private void OnCollectObservableInstruments() | ||
{ | ||
this.observableInstrumentsSource?.RecordObservableInstruments(); | ||
} | ||
|
||
private void MeasurementRecordedDouble(Instrument instrument, double value, ReadOnlySpan<KeyValuePair<string, object?>> tagsRos, object? userState) | ||
{ | ||
var meterProvider = this.meterProviderSdk; | ||
|
||
if (meterProvider.ViewCount > 0) | ||
{ | ||
meterProvider.MeasurementRecordedDouble(instrument, value, tagsRos, userState); | ||
} | ||
else | ||
{ | ||
meterProvider.MeasurementRecordedDoubleSingleStream(instrument, value, tagsRos, userState); | ||
} | ||
} | ||
|
||
private void MeasurementRecordedLong(Instrument instrument, long value, ReadOnlySpan<KeyValuePair<string, object?>> tagsRos, object? userState) | ||
{ | ||
var meterProvider = this.meterProviderSdk; | ||
|
||
if (meterProvider.ViewCount > 0) | ||
{ | ||
meterProvider.MeasurementRecordedLong(instrument, value, tagsRos, userState); | ||
} | ||
else | ||
{ | ||
meterProvider.MeasurementRecordedLongSingleStream(instrument, value, tagsRos, userState); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
src/OpenTelemetry.Extensions.Hosting/OpenTelemetryMetricsBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// <copyright file="OpenTelemetryMetricsBuilderExtensions.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.Diagnostics; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.DependencyInjection.Extensions; | ||
using OpenTelemetry.Internal; | ||
using OpenTelemetry.Metrics; | ||
|
||
namespace Microsoft.Extensions.Diagnostics.Metrics; | ||
|
||
/// <summary> | ||
/// Contains extension methods for registering OpenTelemetry metrics with an | ||
/// <see cref="IMetricsBuilder"/> instance. | ||
/// </summary> | ||
internal static class OpenTelemetryMetricsBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Adds an OpenTelemetry <see cref="IMetricsListener"/> named 'OpenTelemetry' to the <see cref="IMetricsBuilder"/>. | ||
/// </summary> | ||
/// <remarks> | ||
/// Note: This is safe to be called multiple times and by library authors. | ||
/// Only a single <see cref="MeterProvider"/> will be created for a given | ||
/// <see cref="IServiceCollection"/>. | ||
/// </remarks> | ||
/// <param name="metricsBuilder"><see cref="IMetricsBuilder"/>.</param> | ||
/// <returns>The supplied <see cref="IMetricsBuilder"/> for chaining | ||
/// calls.</returns> | ||
public static IMetricsBuilder UseOpenTelemetry( | ||
this IMetricsBuilder metricsBuilder) | ||
=> UseOpenTelemetry(metricsBuilder, b => { }); | ||
|
||
/// <summary> | ||
/// Adds an OpenTelemetry <see cref="IMetricsListener"/> named 'OpenTelemetry' to the <see cref="IMetricsBuilder"/>. | ||
/// </summary> | ||
/// <remarks><inheritdoc cref="UseOpenTelemetry(IMetricsBuilder)" path="/remarks"/></remarks> | ||
/// <param name="metricsBuilder"><see cref="IMetricsBuilder"/>.</param> | ||
/// <param name="configure"><see cref="MeterProviderBuilder"/> | ||
/// configuration callback.</param> | ||
/// <returns>The supplied <see cref="IMetricsBuilder"/> for chaining | ||
/// calls.</returns> | ||
public static IMetricsBuilder UseOpenTelemetry( | ||
this IMetricsBuilder metricsBuilder, | ||
Action<MeterProviderBuilder> configure) | ||
{ | ||
Guard.ThrowIfNull(metricsBuilder); | ||
|
||
RegisterMetricsListener(metricsBuilder.Services, configure); | ||
|
||
return metricsBuilder; | ||
} | ||
|
||
internal static void RegisterMetricsListener( | ||
IServiceCollection services, | ||
Action<MeterProviderBuilder> configure) | ||
{ | ||
Debug.Assert(services != null, "services was null"); | ||
|
||
Guard.ThrowIfNull(configure); | ||
|
||
var builder = new MeterProviderBuilderBase(services!); | ||
|
||
services!.TryAddEnumerable( | ||
ServiceDescriptor.Singleton<IMetricsListener, OpenTelemetryMetricsListener>()); | ||
|
||
configure(builder); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.