Add production features: slog adapter, scan helpers, slow query logging, pool stats, tracer passthrough, test tx isolation
Some checks failed
CI / test (push) Failing after 13s

- slog.go: SlogLogger adapts *slog.Logger to dbx.Logger interface
- scan.go: Collect[T] and CollectOne[T] generic helpers using pgx.RowToStructByName
- cluster.go: slow query logging via Config.SlowQueryThreshold (Warn level in queryEnd)
- stats.go: PoolStats with Cluster.Stats() aggregating pool stats across all nodes
- config.go/node.go: NodeConfig.Tracer passthrough for pgx.QueryTracer (OpenTelemetry)
- options.go: WithSlowQueryThreshold and WithTracer functional options
- dbxtest/tx.go: RunInTx runs callback in always-rolled-back transaction for test isolation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-23 00:19:26 +03:00
parent 7d25e1b73e
commit 2c9af28548
16 changed files with 495 additions and 29 deletions

View File

@@ -17,12 +17,13 @@ type Cluster struct {
replicas []*Node
all []*Node // master + replicas for health checker
balancer Balancer
retrier *retrier
health *healthChecker
logger Logger
metrics *MetricsHook
closed atomic.Bool
balancer Balancer
retrier *retrier
health *healthChecker
logger Logger
metrics *MetricsHook
slowQueryThreshold time.Duration
closed atomic.Bool
}
// NewCluster creates a Cluster, connecting to all configured nodes.
@@ -53,13 +54,14 @@ func NewCluster(ctx context.Context, cfg Config) (*Cluster, error) {
all = append(all, replicas...)
c := &Cluster{
master: master,
replicas: replicas,
all: all,
balancer: NewRoundRobinBalancer(),
retrier: newRetrier(cfg.Retry, cfg.Logger, cfg.Metrics),
logger: cfg.Logger,
metrics: cfg.Metrics,
master: master,
replicas: replicas,
all: all,
balancer: NewRoundRobinBalancer(),
retrier: newRetrier(cfg.Retry, cfg.Logger, cfg.Metrics),
logger: cfg.Logger,
metrics: cfg.Metrics,
slowQueryThreshold: cfg.SlowQueryThreshold,
}
c.health = newHealthChecker(all, cfg.HealthCheck, cfg.Logger, cfg.Metrics)
@@ -232,6 +234,13 @@ func (c *Cluster) queryEnd(ctx context.Context, node, sql string, err error, d t
if c.metrics != nil && c.metrics.OnQueryEnd != nil {
c.metrics.OnQueryEnd(ctx, node, sql, err, d)
}
if c.slowQueryThreshold > 0 && d >= c.slowQueryThreshold {
c.logger.Warn(ctx, "dbx: slow query",
"node", node,
"duration", d,
"sql", sql,
)
}
}
// errRow implements pgx.Row for error cases.