### Install sqlc-pgx-monitoring Source: https://github.com/amirsalarsafaei/sqlc-pgx-monitoring/blob/master/README.md Install the latest released version of the package using go get. You can also specify a particular version. ```shell go get github.com/amirsalarsafaei/sqlc-pgx-monitoring@latest ``` ```shell go get github.com/amirsalarsafaei/sqlc-pgx-monitoring@v1.7.1 ``` -------------------------------- ### Complete Integration Example with OTel Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt This example shows a production-ready setup integrating database tracing and connection pool monitoring with OpenTelemetry for metrics and traces, and Prometheus for scraping. Ensure OpenTelemetry exporters and providers are configured correctly. ```go package main import ( "context" "log/slog" "net/http" "os" "time" "github.com/jackc/pgx/v5/pgxpool" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.17.0" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/amirsalarsafaei/sqlc-pgx-monitoring/dbtracer" "github.com/amirsalarsafaei/sqlc-pgx-monitoring/poolstatus" ) func main() { ctx := context.Background() logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) // 1. Build OTel resource res, _ := resource.New(ctx, resource.WithAttributes(semconv.ServiceName("my-service")), ) // 2. Trace provider → OTLP gRPC traceExp, _ := otlptracegrpc.New(ctx, otlptracegrpc.WithEndpoint("localhost:4317"), otlptracegrpc.WithInsecure(), ) tp := sdktrace.NewTracerProvider( sdktrace.WithBatcher(traceExp), sdktrace.WithResource(res), ) otel.SetTracerProvider(tp) defer tp.Shutdown(ctx) // 3. Meter provider → OTLP gRPC + Prometheus scrape endpoint metricExp, _ := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithEndpoint("localhost:4317"), otlpmetricgrpc.WithInsecure(), ) promExp, _ := prometheus.New() mp := metric.NewMeterProvider( metric.WithResource(res), metric.WithReader(metric.NewPeriodicReader(metricExp, metric.WithInterval(10*time.Second))), metric.WithReader(promExp), ) otel.SetMeterProvider(mp) defer mp.Shutdown(ctx) // 4. Serve Prometheus metrics go http.ListenAndServe(":9090", promhttp.Handler()) // 5. Build the tracer dbTracer, err := dbtracer.NewDBTracer( "mydb", dbtracer.WithLogger(logger), dbtracer.WithMeterProvider(mp), dbtracer.WithTraceProvider(tp), dbtracer.WithLogArgs(true), dbtracer.WithLogArgsLenLimit(512), dbtracer.WithIncludeSpanNameSuffix(true), dbtracer.WithShouldLog(func(e error) bool { return e != nil }), ) if err != nil { logger.Error("failed to create db tracer", "err", err) os.Exit(1) } // 6. Wire tracer into pgxpool cfg, _ := pgxpool.ParseConfig("postgres://user:pass@localhost:5432/mydb?sslmode=disable") cfg.ConnConfig.Tracer = dbTracer pool, err := pgxpool.NewWithConfig(ctx, cfg) if err != nil { logger.Error("failed to connect", "err", err) os.Exit(1) } defer pool.Close() // 7. Register pool status monitoring if err := poolstatus.Register(pool, poolstatus.WithMeterProvider(mp)); err != nil { logger.Error("failed to register pool status", "err", err) os.Exit(1) } // 8. Execute a sqlc-generated named query — span name: "postgresql.query GetUser" // SQL file: -- name: GetUser :one // SELECT id, name FROM users WHERE id = $1 var name string err = pool.QueryRow(ctx, "-- name: GetUser :one\nSELECT name FROM users WHERE id = $1", 42, ).Scan(&name) if err != nil { logger.Error("query failed", "err", err) } } ``` -------------------------------- ### Import sqlc-pgx-monitoring Package Source: https://github.com/amirsalarsafaei/sqlc-pgx-monitoring/blob/master/README.md Import the dbtracer package into your Go project to start using the monitoring capabilities. ```go import "github.com/amirsalarsafaei/sqlc-pgx-monitoring/dbtracer" ``` -------------------------------- ### Configure structured logger with WithLogger Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Set a custom `*slog.Logger` for logging database events. Defaults to `slog.Default()` if not specified. Example shows logging query details. ```go import "log/slog" logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelDebug, })) tracer, err := dbtracer.NewDBTracer("mydb", dbtracer.WithLogger(logger), ) // Log output example for a successful query: // {"time":"...","level":"INFO","msg":"query","query_name":"GetUser","query_command":"one", // "sql":"-- name: GetUser :one\nSELECT ...","args":[42],"time":"1.23ms","pid":12345} ``` -------------------------------- ### Append Query Name to Span Names Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Use `WithIncludeSpanNameSuffix(true)` to append the `sqlc` query name to span names, enhancing discoverability in trace UIs. For example, ` ```go tracer, err := dbtracer.NewDBTracer("mydb", dbtracer.WithIncludeSpanNameSuffix(true), ) // Span names become: // "postgresql.query GetUser" // "postgresql.prepare GetUser" // instead of: // "postgresql.query" // "postgresql.prepare" ``` -------------------------------- ### Initialize Custom DB Tracer Source: https://github.com/amirsalarsafaei/sqlc-pgx-monitoring/blob/master/README.md Set up a custom DB tracer with a logger, meter provider, tracer provider, and configure logging options. Use this to integrate detailed database operation logging and tracing. ```go logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) mp := metric.NewMeterProvider() tp := trace.NewTracerProvider() tracer := dbtracer.NewDBTracer( "database_name", dbtracer.WithLogger(logger), dbtracer.WithMeterProvider(mp), dbtracer.WithTraceProvider(tp), dbtracer.WithLogArgs(true), dbtracer.WithLogArgsLenLimit(1000), dbtracer.WithShouldLog(func(err error) bool { return err != nil // Only log when there's an error }), ) ``` -------------------------------- ### Enable Query Argument Logging with sqlc-pgx Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Use `WithLogArgs(true)` to log bound query parameters. Truncate long strings/byte slices with `WithLogArgsLenLimit(n)` to prevent excessive log output. Defaults are `true` for logging and `64` for the length limit. ```go tracer, err := dbtracer.NewDBTracer("mydb", dbtracer.WithLogArgs(true), dbtracer.WithLogArgsLenLimit(128), // []byte args are hex-encoded; long values become: "deadbeef... (truncated 200 bytes)" // string args longer than 128 bytes become: "hello world... (truncated 50 bytes)" ) ``` -------------------------------- ### Create pgx/pgxpool Tracer with NewDBTracer Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Construct a Tracer for pgx connections and pools. Assign it to ConnConfig.Tracer before opening a connection. Supports custom loggers, meter/tracer providers, and logging configurations. ```go package main import ( "context" "log/slog" "os" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/trace" "github.com/amirsalarsafaei/sqlc-pgx-monitoring/dbtracer" ) func main() { ctx := context.Background() logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) // --- pgxpool.Pool usage --- poolConfig, err := pgxpool.ParseConfig("postgres://user:pass@localhost:5432/mydb?sslmode=disable") if err != nil { panic(err) } tracer, err := dbtracer.NewDBTracer( "mydb", dbtracer.WithLogger(logger), dbtracer.WithMeterProvider(metric.NewNoopMeterProvider()), dbtracer.WithTraceProvider(trace.NewNoopTracerProvider()), dbtracer.WithLogArgs(true), dbtracer.WithLogArgsLenLimit(256), dbtracer.WithShouldLog(func(err error) bool { return err != nil }), ) if err != nil { panic(err) // e.g. dbtracer.ErrDatabaseNameEmpty } poolConfig.ConnConfig.Tracer = tracer pool, err := pgxpool.NewWithConfig(ctx, poolConfig) if err != nil { panic(err) } defer pool.Close() // --- pgx.Conn usage --- connConfig, err := pgx.ParseConfig("postgres://user:pass@localhost:5432/mydb?sslmode=disable") if err != nil { panic(err) } connConfig.Tracer = tracer // same tracer instance is reusable conn, err := pgx.ConnectConfig(ctx, connConfig) if err != nil { panic(err) } defer conn.Close(ctx) } ``` -------------------------------- ### Supply Custom OpenTelemetry MeterProvider for Metrics Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Provide a custom `metric.MeterProvider` to record latency histograms and pool statistics. If not provided, it defaults to the global OpenTelemetry provider. This allows for detailed metrics like `db.client.operation.duration`. ```go import ( "go.opentelemetry.io/otel/exporters/prometheus" sdkmetric "go.opentelemetry.io/otel/sdk/metric" ) promExporter, _ := prometheus.New() mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(promExporter)) tracer, err := dbtracer.NewDBTracer("mydb", dbtracer.WithMeterProvider(mp), ) // Metrics exposed: // db.client.operation.duration{db.system="postgresql", db.namespace="mydb", // pgx.operation.type="query", pgx.status="OK", // sqlc.query.name="GetUser", sqlc.query.command="one"} ``` -------------------------------- ### Supply Custom OpenTelemetry TracerProvider for Spans Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Provide a custom `trace.TracerProvider` for creating spans. Defaults to the global OpenTelemetry provider if not set. This enables detailed tracing of database operations like queries, prepares, and connection acquisitions. ```go import ( "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/resource" semconv "go.opentelemetry.io/otel/semconv/v1.17.0" ) traceExporter, _ := otlptracegrpc.New(ctx, otlptracegrpc.WithEndpoint("localhost:4317"), otlptracegrpc.WithInsecure(), ) tp := sdktrace.NewTracerProvider( sdktrace.WithBatcher(traceExporter), sdktrace.WithResource(resource.NewWithAttributes( semconv.SchemaURL, semconv.ServiceName("my-service"), )), ) tracer, err := dbtracer.NewDBTracer("mydb", dbtracer.WithTraceProvider(tp), ) // Spans produced: "postgresql.query", "postgresql.batch", "postgresql.batch.query", // "postgresql.connect", "postgresql.prepare", "postgresql.copy_from", "pgxpool.acquire" ``` -------------------------------- ### NewDBTracer Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Constructs a Tracer that implements all pgx/pgxpool tracer interfaces. It must be assigned to ConnConfig.Tracer before opening a connection or pool. Returns ErrDatabaseNameEmpty if databaseName is an empty string. ```APIDOC ## NewDBTracer — Create a tracer for pgx connections ### Description `NewDBTracer` constructs a `Tracer` that implements all pgx/pgxpool tracer interfaces. It must be assigned to `ConnConfig.Tracer` before opening a connection or pool. Returns `ErrDatabaseNameEmpty` if `databaseName` is an empty string. ### Function Signature ```go func NewDBTracer(databaseName string, options ...DBTracerOption) (*DBTracer, error) ``` ### Parameters - **databaseName** (string) - Required - The name of the database to be used in telemetry. - **options** ([]DBTracerOption) - Optional - Configuration options for the tracer. ### Options - **dbtracer.WithLogger(logger *slog.Logger)**: Sets a structured slog logger. - **dbtracer.WithMeterProvider(mp metric.MeterProvider)**: Sets the OpenTelemetry MeterProvider. - **dbtracer.WithTraceProvider(tp trace.TracerProvider)**: Sets the OpenTelemetry TracerProvider. - **dbtracer.WithLogArgs(logArgs bool)**: Enables logging of query arguments. - **dbtracer.WithLogArgsLenLimit(limit int)**: Sets the limit for the length of logged query arguments. - **dbtracer.WithShouldLog(shouldLog func(err error) bool)**: Controls conditional logging based on a predicate function. ### Returns - **(*DBTracer, error)**: A new DBTracer instance and an error if any occurred during initialization. ``` -------------------------------- ### Custom MeterProvider for pool metrics Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Configure a custom OpenTelemetry MeterProvider for pool statistics. This allows for specific exporter and reader configurations. ```go import ( "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "github.com/amirsalarsafaei/sqlc-pgx-monitoring/poolstatus" ) metricExporter, _ := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithEndpoint("otel-collector:4317"), otlpmetricgrpc.WithInsecure(), ) mp := sdkmetric.NewMeterProvider( sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExporter)), ) err := poolstatus.Register(pool, poolstatus.WithMeterProvider(mp)) ``` -------------------------------- ### Register Pool Status Monitor Source: https://github.com/amirsalarsafaei/sqlc-pgx-monitoring/blob/master/README.md Enable OpenTelemetry metrics for pgxpool connection status. This requires importing the poolstatus package and calling the Register function after creating your pgxpool instance. ```go import ( "github.com/amirsalarsafaei/sqlc-pgx-monitoring/poolstatus" ) // After creating your pgxpool pool, err := pgxpool.NewWithConfig(ctx, poolConfig) if err != nil { return nil, err } // Register pool status monitoring err = poolstatus.Register(pool) if err != nil { log.Fatal("failed to register pool status monitoring:", err) } ``` -------------------------------- ### Customize Latency Histogram Configuration Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Override the default name, unit, description, and explicit bucket boundaries for the `db.client.operation.duration` histogram. Bucket boundaries are specified in seconds. ```go tracer, err := dbtracer.NewDBTracer("mydb", dbtracer.WithLatencyHistogramConfig( "myapp.db.query.duration", // metric name "s", // unit "PostgreSQL query latency for my-app", // optional explicit bucket boundaries (seconds): 0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, ), ) ``` -------------------------------- ### WithLogger Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Configures the *slog.Logger used for query/batch/connect event logging. Defaults to slog.Default(). ```APIDOC ## WithLogger — Set a structured slog logger ### Description Configures the `*slog.Logger` used for query/batch/connect event logging. Defaults to `slog.Default()`. ### Function Signature ```go func WithLogger(logger *slog.Logger) DBTracerOption ``` ### Parameters - **logger** (*slog.Logger) - Required - The structured logger to use for logging events. ### Returns - **DBTracerOption**: An option to configure the logger for the DBTracer. ``` -------------------------------- ### Control logging with WithShouldLog Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Define a predicate function to conditionally suppress log entries. Useful for ignoring specific errors like `pgx.ErrNoRows` and logging only critical issues. ```go import ( "errors" "github.com/jackc/pgx/v5" ) tracer, err := dbtracer.NewDBTracer("mydb", dbtracer.WithShouldLog(func(err error) bool { // suppress ErrNoRows, log everything else return err != nil && !errors.Is(err, pgx.ErrNoRows) }), ) ``` -------------------------------- ### Assign DBTracer to pgxpool.Pool Config Source: https://github.com/amirsalarsafaei/sqlc-pgx-monitoring/blob/master/README.md Before creating a pgxpool.Pool, assign a new DBTracer instance to the pool's ConnConfig.Tracer field. This enables query monitoring for the connection pool. ```go poolConfig.ConnConfig.Tracer = dbtracer.NewDBTracer( "database_name", ) ``` -------------------------------- ### Assign DBTracer to pgx.Conn Config Source: https://github.com/amirsalarsafaei/sqlc-pgx-monitoring/blob/master/README.md Before creating a pgx.Conn, assign a new DBTracer instance to the connection's Tracer field. This enables query monitoring for individual connections. ```go connConfig.Tracer = dbtracer.NewDBTracer( "database_name", ) ``` -------------------------------- ### Register Pool Status Monitor with Custom Options Source: https://github.com/amirsalarsafaei/sqlc-pgx-monitoring/blob/master/README.md Customize pool status monitoring by providing a custom OpenTelemetry meter provider and additional attributes. This allows for more tailored metric collection and labeling. ```go import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) // Register with custom meter provider and attributes err = poolstatus.Register(pool, poolstatus.WithMeterProvider(customMeterProvider), poolstatus.WithAttributes( attribute.String("service.name", "my-service"), attribute.String("db.instance", "production"), ), ) ``` -------------------------------- ### Configure Custom Latency Histogram Source: https://github.com/amirsalarsafaei/sqlc-pgx-monitoring/blob/master/README.md Customize the OpenTelemetry latency histogram by providing a name, unit, and description. This allows for more specific metric tracking. ```go dbtracer.NewDBTracer( "database_name", dbtracer.WithLatencyHistogramConfig( "custom_histogram_name", "ms", "Custom histogram description", ), ) ``` -------------------------------- ### OTel Attribute Keys for dbtracer Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt These constants define attribute keys for OpenTelemetry metrics and spans, used for filtering and querying SQLC and PGX operations. ```go import "github.com/amirsalarsafaei/sqlc-pgx-monitoring/dbtracer" // Span + histogram label: sqlc query name parsed from SQL comment header _ = dbtracer.SQLCQueryNameKey // "sqlc.query.name" // Span + histogram label: sqlc query command (:one, :many, :exec, etc.) _ = dbtracer.SQLCQueryCommandKey // "sqlc.query.command" // Histogram label: pgx operation type (query, batch, connect, prepare, copy_from) _ = dbtracer.PGXOperationTypeKey // "pgx.operation.type" // Span attribute: prepared statement name _ = dbtracer.PGXPrepareStmtNameKey // "pgx.prepare_stmt.name" // Histogram label: "OK", "UNKNOWN_ERROR", or PgError.Severity (e.g. "ERROR", "FATAL") _ = dbtracer.PGXStatusKey // "pgx.status" // Span attribute: PostgreSQL error code (e.g. "23505" for unique constraint) _ = dbtracer.DBStatusCodeKey // "db.response.status_code" // Span attribute: pool connection operation ("acquire" or "release") _ = dbtracer.PGXPoolConnOperationKey // "pgx.pool.operation" ``` -------------------------------- ### Register pgxpool Pool Statistics Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Register pool statistics with OpenTelemetry. Call once after pool creation. Uses the global MeterProvider by default. ```go package main import ( "context" "log" "github.com/jackc/pgx/v5/pgxpool" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "github.com/amirsalarsafaei/sqlc-pgx-monitoring/poolstatus" ) func main() { ctx := context.Background() pool, err := pgxpool.New(ctx, "postgres://user:pass@localhost:5432/mydb") if err != nil { log.Fatal(err) } defer pool.Close() // Minimal registration — uses the global MeterProvider if err := poolstatus.Register(pool); err != nil { log.Fatal("pool status register:", err) } // Registration with custom provider and extra attributes if err := poolstatus.Register(pool, poolstatus.WithMeterProvider(metric.NewNoopMeterProvider()), poolstatus.WithAttributes( attribute.String("service.name", "my-service"), attribute.String("db.instance", "primary"), ), ); err != nil { log.Fatal("pool status register:", err) } // Metrics published (sampled at each OTel collection interval): // db.client.connections.usage{state="used"} — AcquiredConns // db.client.connections.usage{state="idle"} — IdleConns // db.client.connections.max — MaxConns // db.client.connections.pending_requests — ConstructingConns // pgx.pool.acquires — AcquireCount (cumulative) // pgx.pool.canceled_acquires — CanceledAcquireCount // pgx.pool.waited_for_acquires — EmptyAcquireCount // pgx.pool.connections.created — NewConnsCount // pgx.pool.connections.destroyed{reason="lifetime"} — MaxLifetimeDestroyCount // pgx.pool.connections.destroyed{reason="idletime"} — MaxIdleDestroyCount // pgx.pool.acquire.duration — AcquireDuration (seconds, cumulative) // pgx.pool.acquire.wait.duration — EmptyAcquireWaitTime (seconds, cumulative) } ``` -------------------------------- ### WithShouldLog Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Accepts a ShouldLog func(err error) bool predicate. The tracer calls this before emitting any log line; returning false suppresses the log entry entirely. Useful for silencing pgx.ErrNoRows noise or logging only errors. ```APIDOC ## WithShouldLog — Control conditional logging ### Description Accepts a `ShouldLog func(err error) bool` predicate. The tracer calls this before emitting any log line; returning `false` suppresses the log entry entirely. Useful for silencing `pgx.ErrNoRows` noise or logging only errors. ### Function Signature ```go func WithShouldLog(shouldLog func(err error) bool) DBTracerOption ``` ### Parameters - **shouldLog** (func(err error) bool) - Required - A predicate function that returns `true` if the log entry should be emitted, and `false` otherwise. ### Returns - **DBTracerOption**: An option to configure the conditional logging behavior for the DBTracer. ``` -------------------------------- ### Attach Raw SQL Text to Spans Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Set `WithIncludeSQLText(true)` to include the full SQL query as the `db.query.text` attribute on spans. This is disabled by default to prevent sensitive data leakage. ```go tracer, err := dbtracer.NewDBTracer("mydb", dbtracer.WithIncludeSQLText(true), ) // Span attribute added: db.query.text = "-- name: GetUser :one\nSELECT * FROM users WHERE id = $1" ``` -------------------------------- ### Add custom labels to pool metrics Source: https://context7.com/amirsalarsafaei/sqlc-pgx-monitoring/llms.txt Attach custom attributes (labels) to all reported pool metrics. This is useful for filtering and grouping metrics by service, database, or environment. ```go import ( "go.opentelemetry.io/otel/attribute" "github.com/amirsalarsafaei/sqlc-pgx-monitoring/poolstatus" ) err := poolstatus.Register(pool, poolstatus.WithAttributes( attribute.String("service.name", "order-service"), attribute.String("db.name", "orders"), attribute.String("environment", "production"), ), ) // All pool metrics will carry these extra labels, enabling multi-service dashboards. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.