Skip to content

pgx.v5: Add IgnoreError option #3627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions contrib/jackc/pgx.v5/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type config struct {
traceConnect bool
traceAcquire bool
poolStats bool
ignoreError func(error) bool
statsdClient instrumentation.StatsdClient
}

Expand All @@ -30,6 +31,7 @@ func defaultConfig() *config {
tracePrepare: true,
traceConnect: true,
traceAcquire: true,
ignoreError: func(err error) bool { return false },
}
}

Expand Down Expand Up @@ -107,3 +109,10 @@ func WithPoolStats() Option {
cfg.poolStats = true
}
}

// WithIgnoreError specifies a function that determines whether the error should be ignored.
func WithIgnoreError(fn func(err error) bool) Option {
return func(cfg *config) {
cfg.ignoreError = fn
}
}
18 changes: 11 additions & 7 deletions contrib/jackc/pgx.v5/pgx_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (t *pgxTracer) TraceQueryEnd(ctx context.Context, conn *pgx.Conn, data pgx.
if ok {
span.SetTag(tagRowsAffected, data.CommandTag.RowsAffected())
}
finishSpan(ctx, data.Err)
t.finishSpan(ctx, data.Err)
}

func (t *pgxTracer) TraceBatchStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceBatchStartData) context.Context {
Expand Down Expand Up @@ -175,7 +175,7 @@ func (t *pgxTracer) TraceBatchEnd(ctx context.Context, conn *pgx.Conn, data pgx.
t.prevBatchQuery.finish()
t.prevBatchQuery = nil
}
finishSpan(ctx, data.Err)
t.finishSpan(ctx, data.Err)
}

func (t *pgxTracer) TraceCopyFromStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceCopyFromStartData) context.Context {
Expand All @@ -200,7 +200,7 @@ func (t *pgxTracer) TraceCopyFromEnd(ctx context.Context, conn *pgx.Conn, data p
if t.wrapped.copyFrom != nil {
t.wrapped.copyFrom.TraceCopyFromEnd(ctx, conn, data)
}
finishSpan(ctx, data.Err)
t.finishSpan(ctx, data.Err)
}

func (t *pgxTracer) TracePrepareStart(ctx context.Context, conn *pgx.Conn, data pgx.TracePrepareStartData) context.Context {
Expand All @@ -222,7 +222,7 @@ func (t *pgxTracer) TracePrepareEnd(ctx context.Context, conn *pgx.Conn, data pg
if t.wrapped.prepare != nil {
t.wrapped.prepare.TracePrepareEnd(ctx, conn, data)
}
finishSpan(ctx, data.Err)
t.finishSpan(ctx, data.Err)
}

func (t *pgxTracer) TraceConnectStart(ctx context.Context, data pgx.TraceConnectStartData) context.Context {
Expand All @@ -244,7 +244,7 @@ func (t *pgxTracer) TraceConnectEnd(ctx context.Context, data pgx.TraceConnectEn
if t.wrapped.connect != nil {
t.wrapped.connect.TraceConnectEnd(ctx, data)
}
finishSpan(ctx, data.Err)
t.finishSpan(ctx, data.Err)
}

func (t *pgxTracer) TraceAcquireStart(ctx context.Context, pool *pgxpool.Pool, data pgxpool.TraceAcquireStartData) context.Context {
Expand All @@ -266,7 +266,7 @@ func (t *pgxTracer) TraceAcquireEnd(ctx context.Context, pool *pgxpool.Pool, dat
if t.wrapped.poolAcquire != nil {
t.wrapped.poolAcquire.TraceAcquireEnd(ctx, pool, data)
}
finishSpan(ctx, data.Err)
t.finishSpan(ctx, data.Err)
}

func (t *pgxTracer) spanOptions(connConfig *pgx.ConnConfig, op operationType, sqlStatement string, extraOpts ...tracer.StartSpanOption) []tracer.StartSpanOption {
Expand Down Expand Up @@ -300,10 +300,14 @@ func (t *pgxTracer) spanOptions(connConfig *pgx.ConnConfig, op operationType, sq
return opts
}

func finishSpan(ctx context.Context, err error) {
func (t *pgxTracer) finishSpan(ctx context.Context, err error) {
span, ok := tracer.SpanFromContext(ctx)
if !ok {
return
}
if t.cfg.ignoreError != nil && t.cfg.ignoreError(err) {
span.Finish()
return
}
span.Finish(tracer.WithError(err))
}
31 changes: 31 additions & 0 deletions contrib/jackc/pgx.v5/pgx_tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package pgx

import (
"context"
"errors"
"fmt"
"log"
"os"
Expand Down Expand Up @@ -156,6 +157,35 @@ func TestQuery(t *testing.T) {
assert.Equal(t, ps.SpanID(), s.ParentID())
}

func TestIgnoreError(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

opts := append(tracingAllDisabled(), WithTraceQuery(true), WithIgnoreError(func(err error) bool {
return errors.Is(err, context.Canceled)
}))

parent, ctx := tracer.StartSpanFromContext(t.Context(), "parent")
defer parent.Finish()

// Connect
conn := newPoolCreator(nil, opts...)(t, ctx)

ctx, cancel := context.WithCancel(ctx)
// Forcefully cancel the context to simulate an error
cancel()

// Query
var x int
err := conn.QueryRow(ctx, `SELECT 1`).Scan(&x)
require.NoError(t, err)
require.Equal(t, 1, x)

spans := mt.FinishedSpans()
require.Len(t, spans, 1)
require.Equal(t, nil, spans[0].Tag(ext.Error))
}

func TestPrepare(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()
Expand Down Expand Up @@ -342,6 +372,7 @@ func tracingAllDisabled() []Option {
WithTraceBatch(false),
WithTraceCopyFrom(false),
WithTraceAcquire(false),
WithIgnoreError(func(err error) bool { return false }),
}
}

Expand Down
2 changes: 1 addition & 1 deletion ddtrace/tracer/span_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ type FinishConfig struct {
SkipStackFrames uint
}

// NewFinishConfig allows to build a base finish config struct. It accepts the same options as Finish.
// NewFinishConfig allows building a base finish config struct. It accepts the same options as Finish.
// It's useful to reduce the number of operations in any hot path and update it for request/operation specifics.
func NewFinishConfig(opts ...FinishOption) *FinishConfig {
cfg := new(FinishConfig)
Expand Down