Skip to content

Repository files navigation

pgxotel

CI Release Go Reference License Go pgx OpenTelemetry

OpenTelemetry tracing for pgx v5. Attach QueryTracer to any pgx.ConnConfig or pgxpool.Config and every database operation — queries, batch sends, prepared statements, COPY, and connections — is automatically recorded as an OpenTelemetry span.

Features

  • Instruments all five pgx tracer interfaces: QueryTracer, BatchTracer, ConnectTracer, PrepareTracer, and CopyFromTracer
  • Low-cardinality span names: extracts the first SQL keyword (SELECT, INSERT, …) or uses an explicit -- name: Foo comment
  • Follows stable OpenTelemetry semantic conventions (semconv/v1.40.0): db.namespace, db.operation.name, db.query.text, db.collection.name, server.address, server.port
  • db.query.text is opt-in (IncludeStatement: true) to avoid recording sensitive SQL structure by default
  • Accepts an optional TracerProvider for scoped, test-friendly setup; falls back to the global provider when unset

Installation

go get github.com/pgx-contrib/pgxotel

Usage

Connection pool

config, err := pgxpool.ParseConfig(os.Getenv("PGX_DATABASE_URL"))
if err != nil {
    panic(err)
}

config.ConnConfig.Tracer = &pgxotel.QueryTracer{
    Name: "my-service",
}

pool, err := pgxpool.NewWithConfig(context.Background(), config)
if err != nil {
    panic(err)
}
defer pool.Close()

rows, err := pool.Query(context.Background(), "SELECT * FROM customer")
if err != nil {
    panic(err)
}
defer rows.Close()

Named queries

Prefix any SQL string with -- name: <Identifier> to control the span name. The comment is stripped from db.query.text automatically:

rows, err := pool.Query(ctx,
    "-- name: ListActiveCustomers\nSELECT * FROM customer WHERE active = true",
)

This produces a span named ListActiveCustomers instead of SELECT.

Recording SQL text

SQL is not recorded by default. Enable it per-tracer when the query text is not considered sensitive:

config.ConnConfig.Tracer = &pgxotel.QueryTracer{
    Name:             "my-service",
    IncludeStatement: true,
}

Scoped TracerProvider

config.ConnConfig.Tracer = &pgxotel.QueryTracer{
    Name:     "my-service",
    Provider: myTracerProvider,
}

Span attributes

Every span carries the following attributes:

Attribute Value
db.system.name postgresql
db.namespace database name
server.address host
server.port port
db.operation.name SELECT / INSERT / UPDATE / DELETE / UNKNOWN
db.collection.name table name (CopyFrom only)
db.query.text sanitized SQL (opt-in via IncludeStatement)

Development

DevContainer

Open in VS Code with the Dev Containers extension. The environment provides Go, PostgreSQL 18, and Nix automatically.

PGX_DATABASE_URL=postgres://vscode@postgres:5432/pgxotel?sslmode=disable

Nix

nix develop          # enter shell with Go
go tool ginkgo run -r

Run tests

# Unit tests only (no database required)
go tool ginkgo run -r

# With integration tests
export PGX_DATABASE_URL="postgres://localhost/pgxotel?sslmode=disable"
go tool ginkgo run -r

License

MIT

About

OpenTelemetry tracing instrumentation for pgx v5 — spans for queries, batches, prepared statements, COPY, and connections

Topics

Resources

Stars

9 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages