From c89e363bab6758eef452c4ddf502e39c2c9b91a6 Mon Sep 17 00:00:00 2001 From: Alexander Sorokin Date: Sat, 7 Jun 2025 00:02:53 +0300 Subject: [PATCH 1/2] feat: add option to disable tracing --- options.go | 8 ++++++ tracer.go | 78 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/options.go b/options.go index f0411c2..ef552df 100644 --- a/options.go +++ b/options.go @@ -117,6 +117,14 @@ func WithIncludeQueryParameters() Option { }) } +// WithDisableTracing will disable tracing operations minimizing performance overhead it brings. +// Metrics operations are not affected by this option and will still be performed. +func WithDisableTracing() Option { + return optionFunc(func(cfg *tracerConfig) { + cfg.disableTracing = true + }) +} + // StatsOption allows for managing RecordStats configuration using functional options. type StatsOption interface { applyStatsOptions(o *statsOptions) diff --git a/tracer.go b/tracer.go index 844a31a..0d48e4d 100644 --- a/tracer.go +++ b/tracer.go @@ -80,6 +80,7 @@ type Tracer struct { logSQLStatement bool logConnectionDetails bool includeParams bool + disableTracing bool } type tracerConfig struct { @@ -95,6 +96,7 @@ type tracerConfig struct { logSQLStatement bool logConnectionDetails bool includeParams bool + disableTracing bool } // NewTracer returns a new Tracer. @@ -143,6 +145,7 @@ func NewTracer(opts ...Option) *Tracer { logSQLStatement: cfg.logSQLStatement, logConnectionDetails: cfg.logConnectionDetails, includeParams: cfg.includeParams, + disableTracing: cfg.disableTracing, } tracer.createMetrics() @@ -239,12 +242,18 @@ func connectionAttributesFromConfig(config *pgx.ConnConfig) []attribute.KeyValue return nil } +// skipTracing determines whether tracing operations are undesirable or worthless +// and, therefore, should not be performed. +func (t *Tracer) skipTracing(span trace.Span) bool { + return t.disableTracing || !span.IsRecording() +} + // TraceQueryStart is called at the beginning of Query, QueryRow, and Exec calls. // The returned context is used for the rest of the call and will be passed to TraceQueryEnd. func (t *Tracer) TraceQueryStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceQueryStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if !trace.SpanFromContext(ctx).IsRecording() { + if t.skipTracing(trace.SpanFromContext(ctx)) { return ctx } @@ -296,16 +305,20 @@ func (t *Tracer) TraceQueryStart(ctx context.Context, conn *pgx.Conn, data pgx.T // TraceQueryEnd is called at the end of Query, QueryRow, and Exec calls. func (t *Tracer) TraceQueryEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceQueryEndData) { span := trace.SpanFromContext(ctx) - recordSpanError(span, data.Err) t.incrementOperationErrorCount(ctx, data.Err, pgxOperationQuery) + t.recordOperationDuration(ctx, pgxOperationQuery) + + if t.skipTracing(span) { + return + } + + recordSpanError(span, data.Err) if data.Err == nil { span.SetAttributes(RowsAffectedKey.Int64(data.CommandTag.RowsAffected())) } span.End() - - t.recordOperationDuration(ctx, pgxOperationQuery) } // TraceCopyFromStart is called at the beginning of CopyFrom calls. The @@ -314,7 +327,7 @@ func (t *Tracer) TraceQueryEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceQ func (t *Tracer) TraceCopyFromStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceCopyFromStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if !trace.SpanFromContext(ctx).IsRecording() { + if t.skipTracing(trace.SpanFromContext(ctx)) { return ctx } @@ -347,16 +360,19 @@ func (t *Tracer) TraceCopyFromStart(ctx context.Context, conn *pgx.Conn, data pg // TraceCopyFromEnd is called at the end of CopyFrom calls. func (t *Tracer) TraceCopyFromEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceCopyFromEndData) { span := trace.SpanFromContext(ctx) - recordSpanError(span, data.Err) t.incrementOperationErrorCount(ctx, data.Err, pgxOperationCopy) + t.recordOperationDuration(ctx, pgxOperationCopy) + + if t.skipTracing(span) { + return + } if data.Err == nil { span.SetAttributes(RowsAffectedKey.Int64(data.CommandTag.RowsAffected())) } + recordSpanError(span, data.Err) span.End() - - t.recordOperationDuration(ctx, pgxOperationCopy) } // TraceBatchStart is called at the beginning of SendBatch calls. The returned @@ -365,7 +381,7 @@ func (t *Tracer) TraceCopyFromEnd(ctx context.Context, _ *pgx.Conn, data pgx.Tra func (t *Tracer) TraceBatchStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceBatchStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if !trace.SpanFromContext(ctx).IsRecording() { + if t.skipTracing(trace.SpanFromContext(ctx)) { return ctx } @@ -404,7 +420,7 @@ func (t *Tracer) TraceBatchStart(ctx context.Context, conn *pgx.Conn, data pgx.T func (t *Tracer) TraceBatchQuery(ctx context.Context, conn *pgx.Conn, data pgx.TraceBatchQueryData) { t.incrementOperationErrorCount(ctx, data.Err, pgxOperationBatch) - if !trace.SpanFromContext(ctx).IsRecording() { + if t.skipTracing(trace.SpanFromContext(ctx)) { return } @@ -461,12 +477,15 @@ func (t *Tracer) TraceBatchQuery(ctx context.Context, conn *pgx.Conn, data pgx.T // TraceBatchEnd is called at the end of SendBatch calls. func (t *Tracer) TraceBatchEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceBatchEndData) { span := trace.SpanFromContext(ctx) - recordSpanError(span, data.Err) t.incrementOperationErrorCount(ctx, data.Err, pgxOperationBatch) + t.recordOperationDuration(ctx, pgxOperationBatch) - span.End() + if t.skipTracing(span) { + return + } - t.recordOperationDuration(ctx, pgxOperationBatch) + recordSpanError(span, data.Err) + span.End() } // TraceConnectStart is called at the beginning of Connect and ConnectConfig @@ -475,7 +494,7 @@ func (t *Tracer) TraceBatchEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceB func (t *Tracer) TraceConnectStart(ctx context.Context, data pgx.TraceConnectStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if !trace.SpanFromContext(ctx).IsRecording() { + if t.skipTracing(trace.SpanFromContext(ctx)) { return ctx } @@ -507,12 +526,15 @@ func (t *Tracer) TraceConnectStart(ctx context.Context, data pgx.TraceConnectSta // TraceConnectEnd is called at the end of Connect and ConnectConfig calls. func (t *Tracer) TraceConnectEnd(ctx context.Context, data pgx.TraceConnectEndData) { span := trace.SpanFromContext(ctx) - recordSpanError(span, data.Err) t.incrementOperationErrorCount(ctx, data.Err, pgxOperationConnect) + t.recordOperationDuration(ctx, pgxOperationConnect) - span.End() + if t.skipTracing(span) { + return + } - t.recordOperationDuration(ctx, pgxOperationConnect) + recordSpanError(span, data.Err) + span.End() } // TracePrepareStart is called at the beginning of Prepare calls. The returned @@ -521,7 +543,7 @@ func (t *Tracer) TraceConnectEnd(ctx context.Context, data pgx.TraceConnectEndDa func (t *Tracer) TracePrepareStart(ctx context.Context, conn *pgx.Conn, data pgx.TracePrepareStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if !trace.SpanFromContext(ctx).IsRecording() { + if t.skipTracing(trace.SpanFromContext(ctx)) { return ctx } @@ -571,12 +593,15 @@ func (t *Tracer) TracePrepareStart(ctx context.Context, conn *pgx.Conn, data pgx // TracePrepareEnd is called at the end of Prepare calls. func (t *Tracer) TracePrepareEnd(ctx context.Context, _ *pgx.Conn, data pgx.TracePrepareEndData) { span := trace.SpanFromContext(ctx) - recordSpanError(span, data.Err) t.incrementOperationErrorCount(ctx, data.Err, pgxOperationPrepare) + t.recordOperationDuration(ctx, pgxOperationPrepare) - span.End() + if t.skipTracing(span) { + return + } - t.recordOperationDuration(ctx, pgxOperationPrepare) + recordSpanError(span, data.Err) + span.End() } // TraceAcquireStart is called at the beginning of Acquire. @@ -584,7 +609,7 @@ func (t *Tracer) TracePrepareEnd(ctx context.Context, _ *pgx.Conn, data pgx.Trac func (t *Tracer) TraceAcquireStart(ctx context.Context, pool *pgxpool.Pool, data pgxpool.TraceAcquireStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if !trace.SpanFromContext(ctx).IsRecording() { + if t.skipTracing(trace.SpanFromContext(ctx)) { return ctx } @@ -616,12 +641,15 @@ func (t *Tracer) TraceAcquireStart(ctx context.Context, pool *pgxpool.Pool, data // TraceAcquireEnd is called when a connection has been acquired. func (t *Tracer) TraceAcquireEnd(ctx context.Context, _ *pgxpool.Pool, data pgxpool.TraceAcquireEndData) { span := trace.SpanFromContext(ctx) - recordSpanError(span, data.Err) t.incrementOperationErrorCount(ctx, data.Err, pgxOperationAcquire) + t.recordOperationDuration(ctx, pgxOperationAcquire) - span.End() + if t.skipTracing(span) { + return + } - t.recordOperationDuration(ctx, pgxOperationAcquire) + recordSpanError(span, data.Err) + span.End() } func makeParamsAttribute(args []any) attribute.KeyValue { From 5f6b568b23bb52086a2904efdc798654b9ea0a55 Mon Sep 17 00:00:00 2001 From: Alexander Sorokin Date: Sun, 4 Jan 2026 22:53:39 +0300 Subject: [PATCH 2/2] remove option keep optimizations --- options.go | 8 -------- tracer.go | 35 +++++++++++++---------------------- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/options.go b/options.go index ef552df..f0411c2 100644 --- a/options.go +++ b/options.go @@ -117,14 +117,6 @@ func WithIncludeQueryParameters() Option { }) } -// WithDisableTracing will disable tracing operations minimizing performance overhead it brings. -// Metrics operations are not affected by this option and will still be performed. -func WithDisableTracing() Option { - return optionFunc(func(cfg *tracerConfig) { - cfg.disableTracing = true - }) -} - // StatsOption allows for managing RecordStats configuration using functional options. type StatsOption interface { applyStatsOptions(o *statsOptions) diff --git a/tracer.go b/tracer.go index 0d48e4d..ddd4fb7 100644 --- a/tracer.go +++ b/tracer.go @@ -80,7 +80,6 @@ type Tracer struct { logSQLStatement bool logConnectionDetails bool includeParams bool - disableTracing bool } type tracerConfig struct { @@ -96,7 +95,6 @@ type tracerConfig struct { logSQLStatement bool logConnectionDetails bool includeParams bool - disableTracing bool } // NewTracer returns a new Tracer. @@ -145,7 +143,6 @@ func NewTracer(opts ...Option) *Tracer { logSQLStatement: cfg.logSQLStatement, logConnectionDetails: cfg.logConnectionDetails, includeParams: cfg.includeParams, - disableTracing: cfg.disableTracing, } tracer.createMetrics() @@ -242,18 +239,12 @@ func connectionAttributesFromConfig(config *pgx.ConnConfig) []attribute.KeyValue return nil } -// skipTracing determines whether tracing operations are undesirable or worthless -// and, therefore, should not be performed. -func (t *Tracer) skipTracing(span trace.Span) bool { - return t.disableTracing || !span.IsRecording() -} - // TraceQueryStart is called at the beginning of Query, QueryRow, and Exec calls. // The returned context is used for the rest of the call and will be passed to TraceQueryEnd. func (t *Tracer) TraceQueryStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceQueryStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if t.skipTracing(trace.SpanFromContext(ctx)) { + if !trace.SpanFromContext(ctx).IsRecording() { return ctx } @@ -308,7 +299,7 @@ func (t *Tracer) TraceQueryEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceQ t.incrementOperationErrorCount(ctx, data.Err, pgxOperationQuery) t.recordOperationDuration(ctx, pgxOperationQuery) - if t.skipTracing(span) { + if !span.IsRecording() { return } @@ -327,7 +318,7 @@ func (t *Tracer) TraceQueryEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceQ func (t *Tracer) TraceCopyFromStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceCopyFromStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if t.skipTracing(trace.SpanFromContext(ctx)) { + if !trace.SpanFromContext(ctx).IsRecording() { return ctx } @@ -363,7 +354,7 @@ func (t *Tracer) TraceCopyFromEnd(ctx context.Context, _ *pgx.Conn, data pgx.Tra t.incrementOperationErrorCount(ctx, data.Err, pgxOperationCopy) t.recordOperationDuration(ctx, pgxOperationCopy) - if t.skipTracing(span) { + if !span.IsRecording() { return } @@ -381,7 +372,7 @@ func (t *Tracer) TraceCopyFromEnd(ctx context.Context, _ *pgx.Conn, data pgx.Tra func (t *Tracer) TraceBatchStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceBatchStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if t.skipTracing(trace.SpanFromContext(ctx)) { + if !trace.SpanFromContext(ctx).IsRecording() { return ctx } @@ -420,7 +411,7 @@ func (t *Tracer) TraceBatchStart(ctx context.Context, conn *pgx.Conn, data pgx.T func (t *Tracer) TraceBatchQuery(ctx context.Context, conn *pgx.Conn, data pgx.TraceBatchQueryData) { t.incrementOperationErrorCount(ctx, data.Err, pgxOperationBatch) - if t.skipTracing(trace.SpanFromContext(ctx)) { + if !trace.SpanFromContext(ctx).IsRecording() { return } @@ -480,7 +471,7 @@ func (t *Tracer) TraceBatchEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceB t.incrementOperationErrorCount(ctx, data.Err, pgxOperationBatch) t.recordOperationDuration(ctx, pgxOperationBatch) - if t.skipTracing(span) { + if !span.IsRecording() { return } @@ -494,7 +485,7 @@ func (t *Tracer) TraceBatchEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceB func (t *Tracer) TraceConnectStart(ctx context.Context, data pgx.TraceConnectStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if t.skipTracing(trace.SpanFromContext(ctx)) { + if !trace.SpanFromContext(ctx).IsRecording() { return ctx } @@ -529,7 +520,7 @@ func (t *Tracer) TraceConnectEnd(ctx context.Context, data pgx.TraceConnectEndDa t.incrementOperationErrorCount(ctx, data.Err, pgxOperationConnect) t.recordOperationDuration(ctx, pgxOperationConnect) - if t.skipTracing(span) { + if !span.IsRecording() { return } @@ -543,7 +534,7 @@ func (t *Tracer) TraceConnectEnd(ctx context.Context, data pgx.TraceConnectEndDa func (t *Tracer) TracePrepareStart(ctx context.Context, conn *pgx.Conn, data pgx.TracePrepareStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if t.skipTracing(trace.SpanFromContext(ctx)) { + if !trace.SpanFromContext(ctx).IsRecording() { return ctx } @@ -596,7 +587,7 @@ func (t *Tracer) TracePrepareEnd(ctx context.Context, _ *pgx.Conn, data pgx.Trac t.incrementOperationErrorCount(ctx, data.Err, pgxOperationPrepare) t.recordOperationDuration(ctx, pgxOperationPrepare) - if t.skipTracing(span) { + if !span.IsRecording() { return } @@ -609,7 +600,7 @@ func (t *Tracer) TracePrepareEnd(ctx context.Context, _ *pgx.Conn, data pgx.Trac func (t *Tracer) TraceAcquireStart(ctx context.Context, pool *pgxpool.Pool, data pgxpool.TraceAcquireStartData) context.Context { ctx = context.WithValue(ctx, startTimeCtxKey{}, time.Now()) - if t.skipTracing(trace.SpanFromContext(ctx)) { + if !trace.SpanFromContext(ctx).IsRecording() { return ctx } @@ -644,7 +635,7 @@ func (t *Tracer) TraceAcquireEnd(ctx context.Context, _ *pgxpool.Pool, data pgxp t.incrementOperationErrorCount(ctx, data.Err, pgxOperationAcquire) t.recordOperationDuration(ctx, pgxOperationAcquire) - if t.skipTracing(span) { + if !span.IsRecording() { return }