Skip to content

Commit 6fb947f

Browse files
rojivonzshikNinoFloris
authored
Refactor tracing configuration API (#5928)
Continues #5853 Co-authored-by: Nikita Kazmin <vonzshik@gmail.com> Co-authored-by: Nino Floris <mail@ninofloris.com>
1 parent 3efc720 commit 6fb947f

9 files changed

Lines changed: 152 additions & 95 deletions

src/Npgsql/NpgsqlActivitySource.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ internal static void Enrich(Activity activity, NpgsqlConnector connector)
9696
}
9797
}
9898

99-
internal static void ReceivedFirstResponse(Activity activity, NpgsqlTracingOptions? tracingSettings)
99+
internal static void ReceivedFirstResponse(Activity activity, NpgsqlTracingOptions tracingOptions)
100100
{
101-
if (!activity.IsAllDataRequested || tracingSettings?.EnableFirstResponseEvent == false)
101+
if (!activity.IsAllDataRequested || !tracingOptions.EnableFirstResponseEvent)
102102
return;
103103

104104
var activityEvent = new ActivityEvent("received-first-response");

src/Npgsql/NpgsqlCommand.cs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,22 +1710,19 @@ internal void Reset()
17101710

17111711
#region Tracing
17121712

1713-
internal void TraceCommandStart(NpgsqlConnectionStringBuilder settings, NpgsqlTracingOptions? tracingSettings)
1713+
internal void TraceCommandStart(NpgsqlConnectionStringBuilder settings, NpgsqlTracingOptions tracingOptions)
17141714
{
17151715
Debug.Assert(CurrentActivity is null);
1716+
17161717
if (NpgsqlActivitySource.IsEnabled)
17171718
{
1718-
(var enableTracing, string? spanName) = (true, null);
1719-
if (tracingSettings is not null)
1720-
{
1721-
enableTracing = WrappingBatch is not null
1722-
? tracingSettings.FilterBatch?.Invoke(WrappingBatch) ?? true
1723-
: tracingSettings.FilterCommand?.Invoke(this) ?? true;
1719+
var enableTracing = WrappingBatch is not null
1720+
? tracingOptions.BatchFilter?.Invoke(WrappingBatch) ?? true
1721+
: tracingOptions.CommandFilter?.Invoke(this) ?? true;
17241722

1725-
spanName = WrappingBatch is not null
1726-
? tracingSettings.ProvideSpanNameForBatch?.Invoke(WrappingBatch)
1727-
: tracingSettings.ProvideSpanNameForCommand?.Invoke(this);
1728-
}
1723+
var spanName = WrappingBatch is not null
1724+
? tracingOptions.BatchSpanNameProvider?.Invoke(WrappingBatch)
1725+
: tracingOptions.CommandSpanNameProvider?.Invoke(this);
17291726

17301727
if (enableTracing)
17311728
{
@@ -1743,18 +1740,18 @@ internal void TraceCommandEnrich(NpgsqlConnector connector)
17431740
if (CurrentActivity is not null)
17441741
{
17451742
NpgsqlActivitySource.Enrich(CurrentActivity, connector);
1746-
var tracingSettings = connector.DataSource.Configuration.TracingOptions;
1743+
var tracingOptions = connector.DataSource.Configuration.TracingOptions;
17471744
if (WrappingBatch is not null)
1748-
tracingSettings?.EnrichWithBatch?.Invoke(CurrentActivity, WrappingBatch);
1745+
tracingOptions.BatchEnrichmentCallback?.Invoke(CurrentActivity, WrappingBatch);
17491746
else
1750-
tracingSettings?.EnrichWithCommand?.Invoke(CurrentActivity, this);
1747+
tracingOptions.CommandEnrichmentCallback?.Invoke(CurrentActivity, this);
17511748
}
17521749
}
17531750

1754-
internal void TraceReceivedFirstResponse(NpgsqlTracingOptions? tracingSettings)
1751+
internal void TraceReceivedFirstResponse(NpgsqlTracingOptions tracingOptions)
17551752
{
17561753
if (CurrentActivity is not null)
1757-
NpgsqlActivitySource.ReceivedFirstResponse(CurrentActivity, tracingSettings);
1754+
NpgsqlActivitySource.ReceivedFirstResponse(CurrentActivity, tracingOptions);
17581755
}
17591756

17601757
internal void TraceCommandStop()

src/Npgsql/NpgsqlDataSourceBuilder.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,12 @@ public NpgsqlDataSourceBuilder EnableParameterLogging(bool parameterLoggingEnabl
122122
}
123123

124124
/// <summary>
125-
/// Configures tracing options for the DataSource.
125+
/// Configures OpenTelemetry tracing options.
126126
/// </summary>
127-
/// <param name="tracingOptions">Tracing options for the DataSource.</param>
128127
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
129-
public NpgsqlDataSourceBuilder ConfigureTracingOptions(NpgsqlTracingOptions tracingOptions)
128+
public NpgsqlDataSourceBuilder ConfigureTracing(Action<NpgsqlTracingOptionsBuilder> configureAction)
130129
{
131-
_internalBuilder.ConfigureTracingOptions(tracingOptions);
130+
_internalBuilder.ConfigureTracing(configureAction);
132131
return this;
133132
}
134133

src/Npgsql/NpgsqlDataSourceConfiguration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Npgsql;
99

1010
sealed record NpgsqlDataSourceConfiguration(string? Name,
1111
NpgsqlLoggingConfiguration LoggingConfiguration,
12-
NpgsqlTracingOptions? TracingOptions,
12+
NpgsqlTracingOptions TracingOptions,
1313
TransportSecurityHandler TransportSecurityHandler,
1414
IntegratedSecurityHandler userCertificateValidationCallback,
1515
Action<SslClientAuthenticationOptions>? SslClientAuthenticationOptionsCallback,

src/Npgsql/NpgsqlSlimDataSourceBuilder.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public sealed class NpgsqlSlimDataSourceBuilder : INpgsqlTypeMapper
3030

3131
ILoggerFactory? _loggerFactory;
3232
bool _sensitiveDataLoggingEnabled;
33-
NpgsqlTracingOptions? _tracingOptions;
33+
List<Action<NpgsqlTracingOptionsBuilder>>? _tracingOptionsBuilderCallbacks;
3434

3535
TransportSecurityHandler _transportSecurityHandler = new();
3636
RemoteCertificateValidationCallback? _userCertificateValidationCallback;
@@ -119,13 +119,13 @@ public NpgsqlSlimDataSourceBuilder EnableParameterLogging(bool parameterLoggingE
119119
}
120120

121121
/// <summary>
122-
/// Configures tracing options for the DataSource.
122+
/// Configures OpenTelemetry tracing options.
123123
/// </summary>
124-
/// <param name="tracingOptions">Tracing options for the DataSource.</param>
125124
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
126-
public NpgsqlSlimDataSourceBuilder ConfigureTracingOptions(NpgsqlTracingOptions tracingOptions)
125+
public NpgsqlSlimDataSourceBuilder ConfigureTracing(Action<NpgsqlTracingOptionsBuilder> configureAction)
127126
{
128-
_tracingOptions = tracingOptions;
127+
_tracingOptionsBuilderCallbacks ??= new();
128+
_tracingOptionsBuilderCallbacks.Add(configureAction);
129129
return this;
130130
}
131131

@@ -806,12 +806,17 @@ NpgsqlDataSourceConfiguration PrepareConfiguration()
806806

807807
ConfigureDefaultFactories(this);
808808

809+
var tracingOptionsBuilder = new NpgsqlTracingOptionsBuilder();
810+
foreach (var callback in _tracingOptionsBuilderCallbacks ?? (IEnumerable<Action<NpgsqlTracingOptionsBuilder>>)[])
811+
callback.Invoke(tracingOptionsBuilder);
812+
var tracingOptions = tracingOptionsBuilder.Build();
813+
809814
return new(
810815
Name,
811816
_loggerFactory is null
812817
? NpgsqlLoggingConfiguration.NullConfiguration
813818
: new NpgsqlLoggingConfiguration(_loggerFactory, _sensitiveDataLoggingEnabled),
814-
_tracingOptions,
819+
tracingOptions,
815820
_transportSecurityHandler,
816821
_integratedSecurityHandler,
817822
sslClientAuthenticationOptionsCallback,

src/Npgsql/NpgsqlTracingOptions.cs

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using System;
2+
using System.Diagnostics;
3+
4+
namespace Npgsql;
5+
6+
/// <summary>
7+
/// A builder to configure Npgsql's support for OpenTelemetry tracing.
8+
/// </summary>
9+
public sealed class NpgsqlTracingOptionsBuilder
10+
{
11+
Func<NpgsqlCommand, bool>? _commandFilter;
12+
Func<NpgsqlBatch, bool>? _batchFilter;
13+
Action<Activity, NpgsqlCommand>? _commandEnrichmentCallback;
14+
Action<Activity, NpgsqlBatch>? _batchEnrichmentCallback;
15+
Func<NpgsqlCommand, string?>? _commandSpanNameProvider;
16+
Func<NpgsqlBatch, string?>? _batchSpanNameProvider;
17+
bool _enableFirstResponseEvent = true;
18+
19+
internal NpgsqlTracingOptionsBuilder()
20+
{
21+
}
22+
23+
/// <summary>
24+
/// Configures a filter function that determines whether to emit tracing information for an <see cref="NpgsqlCommand"/>.
25+
/// By default, tracing information is emitted for all commands.
26+
/// </summary>
27+
public NpgsqlTracingOptionsBuilder ConfigureCommandFilter(Func<NpgsqlCommand, bool>? commandFilter)
28+
{
29+
_commandFilter = commandFilter;
30+
return this;
31+
}
32+
33+
/// <summary>
34+
/// Configures a filter function that determines whether to emit tracing information for an <see cref="NpgsqlBatch"/>.
35+
/// By default, tracing information is emitted for all batches.
36+
/// </summary>
37+
public NpgsqlTracingOptionsBuilder ConfigureBatchFilter(Func<NpgsqlBatch, bool>? batchFilter)
38+
{
39+
_batchFilter = batchFilter;
40+
return this;
41+
}
42+
43+
/// <summary>
44+
/// Configures a callback that can enrich the <see cref="Activity"/> emitted for the given <see cref="NpgsqlCommand"/>.
45+
/// </summary>
46+
public NpgsqlTracingOptionsBuilder ConfigureCommandEnrichmentCallback(Action<Activity, NpgsqlCommand>? commandEnrichmentCallback)
47+
{
48+
_commandEnrichmentCallback = commandEnrichmentCallback;
49+
return this;
50+
}
51+
52+
/// <summary>
53+
/// Configures a callback that can enrich the <see cref="Activity"/> emitted for the given <see cref="NpgsqlBatch"/>.
54+
/// </summary>
55+
public NpgsqlTracingOptionsBuilder ConfigureBatchEnrichmentCallback(Action<Activity, NpgsqlBatch>? batchEnrichmentCallback)
56+
{
57+
_batchEnrichmentCallback = batchEnrichmentCallback;
58+
return this;
59+
}
60+
61+
/// <summary>
62+
/// Configures a callback that provides the tracing span's name for an <see cref="NpgsqlCommand"/>. If <c>null</c>, the default standard
63+
/// span name is used, which is the database name.
64+
/// </summary>
65+
public NpgsqlTracingOptionsBuilder ConfigureCommandSpanNameProvider(Func<NpgsqlCommand, string?>? commandSpanNameProvider)
66+
{
67+
_commandSpanNameProvider = commandSpanNameProvider;
68+
return this;
69+
}
70+
71+
/// <summary>
72+
/// Configures a callback that provides the tracing span's name for an <see cref="NpgsqlBatch"/>. If <c>null</c>, the default standard
73+
/// span name is used, which is the database name.
74+
/// </summary>
75+
public NpgsqlTracingOptionsBuilder ConfigureBatchSpanNameProvider(Func<NpgsqlBatch, string?>? batchSpanNameProvider)
76+
{
77+
_batchSpanNameProvider = batchSpanNameProvider;
78+
return this;
79+
}
80+
81+
/// <summary>
82+
/// Gets or sets a value indicating whether to enable the "time-to-first-read" event.
83+
/// Default is true to preserve existing behavior.
84+
/// </summary>
85+
public NpgsqlTracingOptionsBuilder EnableFirstResponseEvent(bool enable = true)
86+
{
87+
_enableFirstResponseEvent = enable;
88+
return this;
89+
}
90+
91+
internal NpgsqlTracingOptions Build() => new()
92+
{
93+
CommandFilter = _commandFilter,
94+
BatchFilter = _batchFilter,
95+
CommandEnrichmentCallback = _commandEnrichmentCallback,
96+
BatchEnrichmentCallback = _batchEnrichmentCallback,
97+
CommandSpanNameProvider = _commandSpanNameProvider,
98+
BatchSpanNameProvider = _batchSpanNameProvider,
99+
EnableFirstResponseEvent = _enableFirstResponseEvent
100+
};
101+
}
102+
103+
sealed class NpgsqlTracingOptions
104+
{
105+
internal Func<NpgsqlCommand, bool>? CommandFilter { get; init; }
106+
internal Func<NpgsqlBatch, bool>? BatchFilter { get; init; }
107+
internal Action<Activity, NpgsqlCommand>? CommandEnrichmentCallback { get; init; }
108+
internal Action<Activity, NpgsqlBatch>? BatchEnrichmentCallback { get; init; }
109+
internal Func<NpgsqlCommand, string?>? CommandSpanNameProvider { get; init; }
110+
internal Func<NpgsqlBatch, string?>? BatchSpanNameProvider { get; init; }
111+
internal bool EnableFirstResponseEvent { get; init; }
112+
}

src/Npgsql/PublicAPI.Shipped.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -767,8 +767,6 @@ Npgsql.NpgsqlSlimDataSourceBuilder.UsePhysicalConnectionInitializer(System.Actio
767767
Npgsql.NpgsqlSlimDataSourceBuilder.UseRootCertificate(System.Security.Cryptography.X509Certificates.X509Certificate2? rootCertificate) -> Npgsql.NpgsqlSlimDataSourceBuilder!
768768
Npgsql.NpgsqlSlimDataSourceBuilder.UseRootCertificateCallback(System.Func<System.Security.Cryptography.X509Certificates.X509Certificate2!>? rootCertificateCallback) -> Npgsql.NpgsqlSlimDataSourceBuilder!
769769
Npgsql.NpgsqlSlimDataSourceBuilder.UseUserCertificateValidationCallback(System.Net.Security.RemoteCertificateValidationCallback! userCertificateValidationCallback) -> Npgsql.NpgsqlSlimDataSourceBuilder!
770-
Npgsql.NpgsqlTracingOptions
771-
Npgsql.NpgsqlTracingOptions.NpgsqlTracingOptions() -> void
772770
Npgsql.NpgsqlTransaction
773771
Npgsql.NpgsqlTransaction.Connection.get -> Npgsql.NpgsqlConnection?
774772
Npgsql.PostgresErrorCodes

src/Npgsql/PublicAPI.Unshipped.txt

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ Npgsql.NpgsqlDataSourceBuilder.MapComposite(System.Type! clrType, string? pgName
99
Npgsql.NpgsqlDataSourceBuilder.MapComposite<T>(string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> Npgsql.NpgsqlDataSourceBuilder!
1010
Npgsql.NpgsqlDataSourceBuilder.MapEnum(System.Type! clrType, string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> Npgsql.NpgsqlDataSourceBuilder!
1111
Npgsql.NpgsqlDataSourceBuilder.MapEnum<TEnum>(string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> Npgsql.NpgsqlDataSourceBuilder!
12-
Npgsql.NpgsqlDataSourceBuilder.ConfigureTracingOptions(Npgsql.NpgsqlTracingOptions! tracingOptions) -> Npgsql.NpgsqlDataSourceBuilder!
12+
Npgsql.NpgsqlDataSourceBuilder.ConfigureTracing(System.Action<Npgsql.NpgsqlTracingOptionsBuilder!>! configureAction) -> Npgsql.NpgsqlDataSourceBuilder!
1313
Npgsql.NpgsqlDataSourceBuilder.UseNegotiateOptionsCallback(System.Action<System.Net.Security.NegotiateAuthenticationClientOptions!>? negotiateOptionsCallback) -> Npgsql.NpgsqlDataSourceBuilder!
1414
Npgsql.NpgsqlDataSourceBuilder.UseSslClientAuthenticationOptionsCallback(System.Action<System.Net.Security.SslClientAuthenticationOptions!>? sslClientAuthenticationOptionsCallback) -> Npgsql.NpgsqlDataSourceBuilder!
1515
Npgsql.NpgsqlMetricsOptions
1616
Npgsql.NpgsqlMetricsOptions.NpgsqlMetricsOptions() -> void
17-
Npgsql.NpgsqlSlimDataSourceBuilder.ConfigureTracingOptions(Npgsql.NpgsqlTracingOptions! tracingOptions) -> Npgsql.NpgsqlSlimDataSourceBuilder!
17+
Npgsql.NpgsqlSlimDataSourceBuilder.ConfigureTracing(System.Action<Npgsql.NpgsqlTracingOptionsBuilder!>! configureAction) -> Npgsql.NpgsqlSlimDataSourceBuilder!
1818
Npgsql.NpgsqlSlimDataSourceBuilder.EnableGeometricTypes() -> Npgsql.NpgsqlSlimDataSourceBuilder!
1919
Npgsql.NpgsqlSlimDataSourceBuilder.EnableJsonTypes() -> Npgsql.NpgsqlSlimDataSourceBuilder!
2020
Npgsql.NpgsqlSlimDataSourceBuilder.EnableNetworkTypes() -> Npgsql.NpgsqlSlimDataSourceBuilder!
@@ -24,20 +24,14 @@ Npgsql.NpgsqlSlimDataSourceBuilder.MapEnum(System.Type! clrType, string? pgName
2424
Npgsql.NpgsqlSlimDataSourceBuilder.MapEnum<TEnum>(string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> Npgsql.NpgsqlSlimDataSourceBuilder!
2525
Npgsql.NpgsqlSlimDataSourceBuilder.UseNegotiateOptionsCallback(System.Action<System.Net.Security.NegotiateAuthenticationClientOptions!>? negotiateOptionsCallback) -> Npgsql.NpgsqlSlimDataSourceBuilder!
2626
Npgsql.NpgsqlSlimDataSourceBuilder.UseSslClientAuthenticationOptionsCallback(System.Action<System.Net.Security.SslClientAuthenticationOptions!>? sslClientAuthenticationOptionsCallback) -> Npgsql.NpgsqlSlimDataSourceBuilder!
27-
Npgsql.NpgsqlTracingOptions.EnableFirstResponseEvent.get -> bool
28-
Npgsql.NpgsqlTracingOptions.EnableFirstResponseEvent.set -> void
29-
Npgsql.NpgsqlTracingOptions.EnrichWithBatch.get -> System.Action<System.Diagnostics.Activity!, Npgsql.NpgsqlBatch!>?
30-
Npgsql.NpgsqlTracingOptions.EnrichWithBatch.set -> void
31-
Npgsql.NpgsqlTracingOptions.EnrichWithCommand.get -> System.Action<System.Diagnostics.Activity!, Npgsql.NpgsqlCommand!>?
32-
Npgsql.NpgsqlTracingOptions.EnrichWithCommand.set -> void
33-
Npgsql.NpgsqlTracingOptions.FilterBatch.get -> System.Func<Npgsql.NpgsqlBatch!, bool>?
34-
Npgsql.NpgsqlTracingOptions.FilterBatch.set -> void
35-
Npgsql.NpgsqlTracingOptions.FilterCommand.get -> System.Func<Npgsql.NpgsqlCommand!, bool>?
36-
Npgsql.NpgsqlTracingOptions.FilterCommand.set -> void
37-
Npgsql.NpgsqlTracingOptions.ProvideSpanNameForBatch.get -> System.Func<Npgsql.NpgsqlBatch!, string?>?
38-
Npgsql.NpgsqlTracingOptions.ProvideSpanNameForBatch.set -> void
39-
Npgsql.NpgsqlTracingOptions.ProvideSpanNameForCommand.get -> System.Func<Npgsql.NpgsqlCommand!, string?>?
40-
Npgsql.NpgsqlTracingOptions.ProvideSpanNameForCommand.set -> void
27+
Npgsql.NpgsqlTracingOptionsBuilder
28+
Npgsql.NpgsqlTracingOptionsBuilder.ConfigureBatchEnrichmentCallback(System.Action<System.Diagnostics.Activity!, Npgsql.NpgsqlBatch!>? batchEnrichmentCallback) -> Npgsql.NpgsqlTracingOptionsBuilder!
29+
Npgsql.NpgsqlTracingOptionsBuilder.ConfigureBatchFilter(System.Func<Npgsql.NpgsqlBatch!, bool>? batchFilter) -> Npgsql.NpgsqlTracingOptionsBuilder!
30+
Npgsql.NpgsqlTracingOptionsBuilder.ConfigureBatchSpanNameProvider(System.Func<Npgsql.NpgsqlBatch!, string?>? batchSpanNameProvider) -> Npgsql.NpgsqlTracingOptionsBuilder!
31+
Npgsql.NpgsqlTracingOptionsBuilder.ConfigureCommandEnrichmentCallback(System.Action<System.Diagnostics.Activity!, Npgsql.NpgsqlCommand!>? commandEnrichmentCallback) -> Npgsql.NpgsqlTracingOptionsBuilder!
32+
Npgsql.NpgsqlTracingOptionsBuilder.ConfigureCommandFilter(System.Func<Npgsql.NpgsqlCommand!, bool>? commandFilter) -> Npgsql.NpgsqlTracingOptionsBuilder!
33+
Npgsql.NpgsqlTracingOptionsBuilder.ConfigureCommandSpanNameProvider(System.Func<Npgsql.NpgsqlCommand!, string?>? commandSpanNameProvider) -> Npgsql.NpgsqlTracingOptionsBuilder!
34+
Npgsql.NpgsqlTracingOptionsBuilder.EnableFirstResponseEvent(bool enable = true) -> Npgsql.NpgsqlTracingOptionsBuilder!
4135
Npgsql.Replication.PgOutput.ReplicationValue.GetFieldName() -> string!
4236
Npgsql.Replication.PgOutput.Messages.ParallelStreamAbortMessage
4337
Npgsql.Replication.PgOutput.Messages.ParallelStreamAbortMessage.AbortLsn.get -> NpgsqlTypes.NpgsqlLogSequenceNumber

0 commit comments

Comments
 (0)