[sdk] Customize known connection histograms buckets (#5008)

This commit is contained in:
James Newton-King 2023-11-03 09:07:07 +08:00 committed by GitHub
parent c8f939e60b
commit 37481f1ee6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 45 deletions

View File

@ -17,6 +17,10 @@
([#5004](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5004))
([#5016](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5016))
* Update `AggregatorStore` to provide known connection metrics with larger
histogram buckets.
([#5008](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5008))
## 1.7.0-alpha.1
Released 2023-Oct-16

View File

@ -372,10 +372,19 @@ internal sealed class AggregatorStore
private static double[] FindDefaultHistogramBounds(in MetricStreamIdentity metricStreamIdentity)
{
if (metricStreamIdentity.Unit == "s" && Metric.DefaultHistogramBoundMappings
if (metricStreamIdentity.Unit == "s")
{
if (Metric.DefaultHistogramBoundShortMappings
.Contains((metricStreamIdentity.MeterName, metricStreamIdentity.InstrumentName)))
{
return Metric.DefaultHistogramBoundsSeconds;
return Metric.DefaultHistogramBoundsShortSeconds;
}
if (Metric.DefaultHistogramBoundLongMappings
.Contains((metricStreamIdentity.MeterName, metricStreamIdentity.InstrumentName)))
{
return Metric.DefaultHistogramBoundsLongSeconds;
}
}
return Metric.DefaultHistogramBounds;

View File

@ -28,23 +28,31 @@ public sealed class Metric
internal const int DefaultExponentialHistogramMaxScale = 20;
internal static readonly double[] DefaultHistogramBounds = new double[] { 0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000 };
internal static readonly double[] DefaultHistogramBoundsSeconds = new double[] { 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 };
internal static readonly HashSet<(string, string)> DefaultHistogramBoundMappings = new()
// Short default histogram bounds. Based on the recommended semantic convention values for http.server.request.duration.
internal static readonly double[] DefaultHistogramBoundsShortSeconds = new double[] { 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 };
internal static readonly HashSet<(string, string)> DefaultHistogramBoundShortMappings = new()
{
("Microsoft.AspNetCore.Hosting", "http.server.request.duration"),
("Microsoft.AspNetCore.Http.Connections", "signalr.server.connection.duration"),
("Microsoft.AspNetCore.RateLimiting", "aspnetcore.rate_limiting.request.time_in_queue"),
("Microsoft.AspNetCore.RateLimiting", "aspnetcore.rate_limiting.request_lease.duration"),
("Microsoft.AspNetCore.Server.Kestrel", "kestrel.connection.duration"),
("Microsoft.AspNetCore.Server.Kestrel", "kestrel.tls_handshake.duration"),
("OpenTelemetry.Instrumentation.AspNetCore", "http.server.request.duration"),
("OpenTelemetry.Instrumentation.Http", "http.client.request.duration"),
("System.Net.Http", "http.client.connection.duration"),
("System.Net.Http", "http.client.request.duration"),
("System.Net.Http", "http.client.request.time_in_queue"),
("System.Net.NameResolution", "dns.lookups.duration"),
};
// Long default histogram bounds. Not based on a standard. May change in the future.
internal static readonly double[] DefaultHistogramBoundsLongSeconds = new double[] { 0, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 };
internal static readonly HashSet<(string, string)> DefaultHistogramBoundLongMappings = new()
{
("Microsoft.AspNetCore.Http.Connections", "signalr.server.connection.duration"),
("Microsoft.AspNetCore.Server.Kestrel", "kestrel.connection.duration"),
("System.Net.Http", "http.client.connection.duration"),
};
private readonly AggregatorStore aggStore;
internal Metric(

View File

@ -239,27 +239,23 @@ public abstract class AggregatorTestsBase
}
[Theory]
[InlineData("Microsoft.AspNetCore.Hosting", "http.server.request.duration")]
[InlineData("Microsoft.AspNetCore.Http.Connections", "signalr.server.connection.duration")]
[InlineData("Microsoft.AspNetCore.RateLimiting", "aspnetcore.rate_limiting.request_lease.duration")]
[InlineData("Microsoft.AspNetCore.RateLimiting", "aspnetcore.rate_limiting.request.time_in_queue")]
[InlineData("Microsoft.AspNetCore.Server.Kestrel", "kestrel.connection.duration")]
[InlineData("Microsoft.AspNetCore.Server.Kestrel", "kestrel.tls_handshake.duration")]
[InlineData("OpenTelemetry.Instrumentation.AspNetCore", "http.server.duration")]
[InlineData("OpenTelemetry.Instrumentation.Http", "http.client.duration")]
[InlineData("System.Net.Http", "http.client.connection.duration")]
[InlineData("System.Net.Http", "http.client.request.duration")]
[InlineData("System.Net.Http", "http.client.request.time_in_queue")]
[InlineData("System.Net.NameResolution", "dns.lookups.duration")]
[InlineData("General.App", "simple.alternative.counter")]
public void HistogramBucketsDefaultUpdatesForSecondsTest(string meterName, string instrumentName)
{
RunTest(meterName, instrumentName, unit: "s");
RunTest(meterName, instrumentName, unit: "ms");
RunTest(meterName, instrumentName, unit: "By");
RunTest(meterName, instrumentName, unit: null);
void RunTest(string meterName, string instrumentName, string unit)
[InlineData("Microsoft.AspNetCore.Hosting", "http.server.request.duration", "s", KnownHistogramBuckets.DefaultShortSeconds)]
[InlineData("Microsoft.AspNetCore.Hosting", "http.server.request.duration", "ms", KnownHistogramBuckets.Default)]
[InlineData("Microsoft.AspNetCore.Hosting", "http.server.request.duration", "By", KnownHistogramBuckets.Default)]
[InlineData("Microsoft.AspNetCore.Hosting", "http.server.request.duration", null, KnownHistogramBuckets.Default)]
[InlineData("Microsoft.AspNetCore.Http.Connections", "signalr.server.connection.duration", "s", KnownHistogramBuckets.DefaultLongSeconds)]
[InlineData("Microsoft.AspNetCore.RateLimiting", "aspnetcore.rate_limiting.request_lease.duration", "s", KnownHistogramBuckets.DefaultShortSeconds)]
[InlineData("Microsoft.AspNetCore.RateLimiting", "aspnetcore.rate_limiting.request.time_in_queue", "s", KnownHistogramBuckets.DefaultShortSeconds)]
[InlineData("Microsoft.AspNetCore.Server.Kestrel", "kestrel.connection.duration", "s", KnownHistogramBuckets.DefaultLongSeconds)]
[InlineData("Microsoft.AspNetCore.Server.Kestrel", "kestrel.tls_handshake.duration", "s", KnownHistogramBuckets.DefaultShortSeconds)]
[InlineData("OpenTelemetry.Instrumentation.AspNetCore", "http.server.duration", "ms", KnownHistogramBuckets.Default)]
[InlineData("OpenTelemetry.Instrumentation.Http", "http.client.duration", "ms", KnownHistogramBuckets.Default)]
[InlineData("System.Net.Http", "http.client.connection.duration", "s", KnownHistogramBuckets.DefaultLongSeconds)]
[InlineData("System.Net.Http", "http.client.request.duration", "s", KnownHistogramBuckets.DefaultShortSeconds)]
[InlineData("System.Net.Http", "http.client.request.time_in_queue", "s", KnownHistogramBuckets.DefaultShortSeconds)]
[InlineData("System.Net.NameResolution", "dns.lookups.duration", "s", KnownHistogramBuckets.DefaultShortSeconds)]
[InlineData("General.App", "simple.alternative.counter", "s", KnownHistogramBuckets.Default)]
public void HistogramBucketsDefaultUpdatesForSecondsTest(string meterName, string instrumentName, string unit, KnownHistogramBuckets expectedHistogramBuckets)
{
using var meter = new Meter(meterName);
@ -274,12 +270,18 @@ public abstract class AggregatorTestsBase
maxMetricPoints: 1024,
this.emitOverflowAttribute);
Assert.NotNull(aggregatorStore.HistogramBounds);
Assert.Equal(
unit == "s" && Metric.DefaultHistogramBoundMappings.Contains((meterName, instrumentName)) ?
Metric.DefaultHistogramBoundsSeconds : Metric.DefaultHistogramBounds,
aggregatorStore.HistogramBounds);
KnownHistogramBuckets actualHistogramBounds = KnownHistogramBuckets.Default;
if (aggregatorStore.HistogramBounds == Metric.DefaultHistogramBoundsShortSeconds)
{
actualHistogramBounds = KnownHistogramBuckets.DefaultShortSeconds;
}
else if (aggregatorStore.HistogramBounds == Metric.DefaultHistogramBoundsLongSeconds)
{
actualHistogramBounds = KnownHistogramBuckets.DefaultLongSeconds;
}
Assert.NotNull(aggregatorStore.HistogramBounds);
Assert.Equal(expectedHistogramBuckets, actualHistogramBounds);
}
internal static void AssertExponentialBucketsAreCorrect(Base2ExponentialBucketHistogram expectedHistogram, ExponentialHistogramData data)

View File

@ -0,0 +1,35 @@
// <copyright file="KnownHistogramBuckets.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>
namespace OpenTelemetry.Metrics.Tests;
public enum KnownHistogramBuckets
{
/// <summary>
/// Default OpenTelemetry semantic convention buckets.
/// </summary>
Default,
/// <summary>
/// Buckets for up to 10 seconds.
/// </summary>
DefaultShortSeconds,
/// <summary>
/// Buckets for up to 300 seconds.
/// </summary>
DefaultLongSeconds,
}