From 4cba7a1aefb64f96c147839347ad2a9b232bb745 Mon Sep 17 00:00:00 2001 From: Christophe Chevalier Date: Thu, 1 Aug 2024 15:54:50 +0200 Subject: [PATCH] Fdb: rename FdbMetricsReporter to FdbClientInstrumentation and add OTEL instrumentation helpers - Move the ActivitySource to FdbClientInstrumentation, so that it could be used by other parts of the library - Standardize the name of the Trace, Metrics and HealthChecks to "FoundationDB.Client" (with uppercase 'B' !) --- .../FdbAspireComponentExtensions.cs | 30 ++------------ .../FdbClientOpenTelemtryExtensions.cs | 40 +++++++++++++++++++ ...eporter.cs => FdbClientInstrumentation.cs} | 14 +++++-- FoundationDB.Client/FdbOperationContext.cs | 31 +++++++------- FoundationDB.Client/FdbTransaction.cs | 22 +++++----- 5 files changed, 79 insertions(+), 58 deletions(-) create mode 100644 Aspire.FoundationDB/FdbClientOpenTelemtryExtensions.cs rename FoundationDB.Client/{FdbMetricsReporter.cs => FdbClientInstrumentation.cs} (93%) diff --git a/Aspire.FoundationDB/FdbAspireComponentExtensions.cs b/Aspire.FoundationDB/FdbAspireComponentExtensions.cs index a657f0ff..6f334e89 100644 --- a/Aspire.FoundationDB/FdbAspireComponentExtensions.cs +++ b/Aspire.FoundationDB/FdbAspireComponentExtensions.cs @@ -21,15 +21,13 @@ namespace Microsoft.Extensions.Hosting using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; - using OpenTelemetry.Metrics; + using OpenTelemetry.Trace; /// Provides extension methods for adding FoundationDB to the local DI container. [PublicAPI] public static class FdbAspireComponentExtensions { - private const string ActivitySourceName = "FoundationDb.Client"; - private const string DefaultConfigSectionName = "Aspire:FoundationDb:Client"; /// Add support for connecting to a FoundationDB cluster @@ -251,13 +249,13 @@ private static IHostApplicationBuilder AddFoundationDb(this IHostApplicationBuil if (!settings.DisableTracing) { builder.Services.AddOpenTelemetry() - .WithTracing(traceBuilder => traceBuilder.AddSource(ActivitySourceName)); + .WithTracing(traceBuilder => traceBuilder.AddFoundationDbInstrumentation()); } if (!settings.DisableHealthChecks) { var check = new HealthCheckRegistration( - "FoundationDb.Client", + FdbClientInstrumentation.HealthCheckName, sp => { try @@ -288,27 +286,7 @@ private static IHostApplicationBuilder AddFoundationDb(this IHostApplicationBuil if (!settings.DisableMetrics) { builder.Services.AddOpenTelemetry() - .WithMetrics((meterProviderBuilder) => - { - meterProviderBuilder - .AddMeter("FdbClient") - .AddView("db.fdb.client.transactions.duration", - new ExplicitBucketHistogramConfiguration - { - Boundaries = [ 0, 0.001, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ], - }) - .AddView("db.fdb.client.operations.duration", - new ExplicitBucketHistogramConfiguration - { - Boundaries = [ 0, 0.001, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ], - }) - .AddView("db.fdb.client.operations.size", - new ExplicitBucketHistogramConfiguration - { - Boundaries = [ 0, 10, 20, 50, 100, 200, 500, 1_000, 2_000, 5_000, 10_000, 20_000, 50_000, 100_000, 200_000, 500_000, 1_000_000, 2_000_000, 5_000_000, 10_000_000 ] - }) - ; - }); + .WithMetrics((meterBuilder) => meterBuilder.AddFoundationDbInstrumentation()); } return builder; diff --git a/Aspire.FoundationDB/FdbClientOpenTelemtryExtensions.cs b/Aspire.FoundationDB/FdbClientOpenTelemtryExtensions.cs new file mode 100644 index 00000000..c6386b5b --- /dev/null +++ b/Aspire.FoundationDB/FdbClientOpenTelemtryExtensions.cs @@ -0,0 +1,40 @@ +#region Copyright (c) 2023-2024 SnowBank SAS +// +// All rights are reserved. Reproduction or transmission in whole or in part, in +// any form or by any means, electronic, mechanical or otherwise, is prohibited +// without the prior written consent of the copyright owner. +// +#endregion + +namespace OpenTelemetry.Trace +{ + using FoundationDB.Client; + using OpenTelemetry.Metrics; + + public static class FdbClientOpenTelemtryExtensions + { + + public static TracerProviderBuilder AddFoundationDbInstrumentation(this TracerProviderBuilder provider) + { + provider.AddSource(FdbClientInstrumentation.ActivityName); + return provider; + } + + public static MeterProviderBuilder AddFoundationDbInstrumentation(this MeterProviderBuilder provider) + { + provider.AddMeter(FdbClientInstrumentation.MeterName) + .AddView( + "db.fdb.client.transactions.duration", + new ExplicitBucketHistogramConfiguration { Boundaries = [ 0, 0.001, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ], }) + .AddView( + "db.fdb.client.operations.duration", + new ExplicitBucketHistogramConfiguration { Boundaries = [ 0, 0.001, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ], }) + .AddView( + "db.fdb.client.operations.size", + new ExplicitBucketHistogramConfiguration { Boundaries = [ 0, 10, 20, 50, 100, 200, 500, 1_000, 2_000, 5_000, 10_000, 20_000, 50_000, 100_000, 200_000, 500_000, 1_000_000, 2_000_000, 5_000_000, 10_000_000 ] }) + ; + return provider; + } + + } +} diff --git a/FoundationDB.Client/FdbMetricsReporter.cs b/FoundationDB.Client/FdbClientInstrumentation.cs similarity index 93% rename from FoundationDB.Client/FdbMetricsReporter.cs rename to FoundationDB.Client/FdbClientInstrumentation.cs index 004afaec..be604313 100644 --- a/FoundationDB.Client/FdbMetricsReporter.cs +++ b/FoundationDB.Client/FdbClientInstrumentation.cs @@ -12,14 +12,20 @@ namespace FoundationDB.Client using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Metrics; + using OpenTelemetry.Metrics; - public static class FdbMetricsReporter + public static class FdbClientInstrumentation { - private const string METER_NAME = "FdbClient"; - private const string VERSION = "0.1.0"; //TODO: which version? + public const string ActivityName = "FoundationDB.Client"; + public const string ActivityVersion = "0.1.0"; //TODO: which version? + public const string MeterName = "FoundationDB.Client"; + public const string MeterVersion = "0.1.0"; //TODO: which version? + public const string HealthCheckName = "FoundationDB.Client"; - private static Meter Meter { get; } = new(METER_NAME, VERSION); //TODO: version? + internal static readonly ActivitySource ActivitySource = new(ActivityName, ActivityVersion); + + private static Meter Meter { get; } = new(MeterName, MeterVersion); //TODO: version? private static UpDownCounter TransactionsExecuting { get; } = Meter.CreateUpDownCounter( "db.fdb.client.transactions.executing", diff --git a/FoundationDB.Client/FdbOperationContext.cs b/FoundationDB.Client/FdbOperationContext.cs index 7323da25..dfe6e06e 100644 --- a/FoundationDB.Client/FdbOperationContext.cs +++ b/FoundationDB.Client/FdbOperationContext.cs @@ -48,9 +48,6 @@ namespace FoundationDB.Client [PublicAPI] public sealed class FdbOperationContext : IDisposable { - //REVIEW: maybe we should find a way to reduce the size of this class? (it's already almost at 100 bytes !) - - private static readonly ActivitySource ActivitySource = new("FoundationDB.Client"); /// The database used by the operation public IFdbDatabase Database => m_db; @@ -746,7 +743,7 @@ internal static async Task ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal ExecuteInternal= 10) diff --git a/FoundationDB.Client/FdbTransaction.cs b/FoundationDB.Client/FdbTransaction.cs index 5e13666a..a3f9df31 100644 --- a/FoundationDB.Client/FdbTransaction.cs +++ b/FoundationDB.Client/FdbTransaction.cs @@ -630,7 +630,7 @@ public Task TryGetAsync(ReadOnlySpan key, IBufferWriter valueW private Task PerformGetOperation(ReadOnlySpan key, bool snapshot) { - FdbMetricsReporter.ReportGet(this); + FdbClientInstrumentation.ReportGet(this); return m_log == null ? m_handler.GetAsync(key, snapshot: snapshot, m_cancellation) : ExecuteLogged(this, key, snapshot); @@ -644,7 +644,7 @@ static Task ExecuteLogged(FdbTransaction self, ReadOnlySpan key, bo private Task PerformGetOperation(ReadOnlySpan key, IBufferWriter valueWriter, bool snapshot) { - FdbMetricsReporter.ReportGet(this); + FdbClientInstrumentation.ReportGet(this); return m_log == null ? m_handler.TryGetAsync(key, valueWriter, snapshot: snapshot, m_cancellation) : ExecuteLogged(this, key, snapshot, valueWriter); @@ -672,7 +672,7 @@ static Task ExecuteLogged(FdbTransaction self, ReadOnlySpan key, boo private Task<(FdbValueCheckResult Result, Slice Actual)> PerformValueCheckOperation(ReadOnlySpan key, Slice expected, bool snapshot) { - FdbMetricsReporter.ReportGet(this); //REVIEW: use a specific operation type for this? + FdbClientInstrumentation.ReportGet(this); //REVIEW: use a specific operation type for this? return m_log == null ? m_handler.CheckValueAsync(key, expected, snapshot: snapshot, m_cancellation) : ExecuteLogged(this, key, expected, snapshot); @@ -704,7 +704,7 @@ public Task GetValuesAsync(ReadOnlySpan keys) private Task PerformGetValuesOperation(ReadOnlySpan keys, bool snapshot) { - FdbMetricsReporter.ReportGet(this, keys.Length); + FdbClientInstrumentation.ReportGet(this, keys.Length); return m_log == null ? m_handler.GetValuesAsync(keys, snapshot: snapshot, m_cancellation) : ExecuteLogged(this, keys, snapshot); @@ -755,7 +755,7 @@ private Task PerformGetRangeOperation( FdbReadMode read, int iteration) { - FdbMetricsReporter.ReportGetRange(this); + FdbClientInstrumentation.ReportGetRange(this); return m_log == null ? m_handler.GetRangeAsync(beginInclusive, endExclusive, limit, reverse, targetBytes, mode, read, iteration, snapshot, m_cancellation) @@ -843,7 +843,7 @@ public Task GetKeyAsync(KeySelector selector) private Task PerformGetKeyOperation(KeySelector selector, bool snapshot) { - FdbMetricsReporter.ReportGetKey(this); + FdbClientInstrumentation.ReportGetKey(this); return m_log == null ? m_handler.GetKeyAsync(selector, snapshot: snapshot, m_cancellation) : ExecuteLogged(this, selector, snapshot); @@ -879,7 +879,7 @@ public Task GetKeysAsync(ReadOnlySpan selectors) private Task PerformGetKeysOperation(ReadOnlySpan selectors, bool snapshot) { - FdbMetricsReporter.ReportGetKey(this, selectors.Length); + FdbClientInstrumentation.ReportGetKey(this, selectors.Length); return m_log == null ? m_handler.GetKeysAsync(selectors, snapshot: snapshot, m_cancellation) : ExecuteLogged(this, selectors, snapshot); @@ -911,7 +911,7 @@ public void Set(ReadOnlySpan key, ReadOnlySpan value) private void PerformSetOperation(ReadOnlySpan key, ReadOnlySpan value) { - FdbMetricsReporter.ReportSet(this); + FdbClientInstrumentation.ReportSet(this); if (m_log == null) { @@ -1071,7 +1071,7 @@ public void Atomic(ReadOnlySpan key, ReadOnlySpan param, FdbMutation private void PerformAtomicOperation(ReadOnlySpan key, ReadOnlySpan param, FdbMutationType type) { - FdbMetricsReporter.ReportAtomicOp(this, type); + FdbClientInstrumentation.ReportAtomicOp(this, type); if (m_log == null) { @@ -1110,7 +1110,7 @@ public void Clear(ReadOnlySpan key) private void PerformClearOperation(ReadOnlySpan key) { - FdbMetricsReporter.ReportClear(this); + FdbClientInstrumentation.ReportClear(this); if (m_log == null) { @@ -1150,7 +1150,7 @@ public void ClearRange(ReadOnlySpan beginKeyInclusive, ReadOnlySpan private void PerformClearRangeOperation(ReadOnlySpan beginKeyInclusive, ReadOnlySpan endKeyExclusive) { - FdbMetricsReporter.ReportClearRange(this); + FdbClientInstrumentation.ReportClearRange(this); if (m_log == null) {