jackc / jackc/pgx

Request for guidance on tracing and logging

Open
#2,021 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
14.3k
Forks
1.1k
Avg merge
6d 9h
Merged PRs (30d)
11

Description

Hey!
With limited resources/knowledge I was trying to add tracer and logger to an application.
The intention is to trace queries and connections to find what's happening with application and database.
However, I was not able to trace/log anything.

I am sure I am missing something please guide.

Kindly guide or point towards resources which can be utilised to enable logger and tracer.

```

config, err := pgxpool.ParseConfig(dsn)
//added logger
m := pgxtrace.CompositeQueryTracer{
Tracers: []pgx.QueryTracer{

&tracelog.TraceLog{
Logger: pgxtrace.NewLogger(&CustomLogger{}),
LogLevel: tracelog.LogLevelDebug,
},
},
}

config.ConnConfig.Tracer = &m

//customer logger which is attached above.
type CustomLogger struct{}

func (cl *CustomLogger) Log(args ...interface{}) {
fmt.Println("Log method called")
fmt.Println(args...)
}

// This is pgx trace package

package pgxtrace

import (
"context"

"github.com/jackc/pgx/v5"
)

var (
_ pgx.QueryTracer = (*CompositeQueryTracer)(nil)
_ pgx.BatchTracer = (*CompositeQueryTracer)(nil)
_ pgx.ConnectTracer = (*CompositeQueryTracer)(nil)
_ pgx.PrepareTracer = (*CompositeQueryTracer)(nil)
_ pgx.CopyFromTracer = (*CompositeQueryTracer)(nil)
)
type CompositeQueryTracer struct {
Tracers []pgx.QueryTracer
}
// CompositeQueryTracer represent a composite query tracer
//type CompositeQueryTracer []pgx.QueryTracer

// TraceConnectStart implements pgx.ConnectTracer.
func (t CompositeQueryTracer) TraceConnectStart(ctx context.Context, data pgx.TraceConnectStartData) context.Context {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.ConnectTracer); ok {
ctx = tracer.TraceConnectStart(ctx, data)
}
}

return ctx
}

// TraceConnectEnd implements pgx.ConnectTracer.
func (t CompositeQueryTracer) TraceConnectEnd(ctx context.Context, data pgx.TraceConnectEndData) {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.ConnectTracer); ok {
tracer.TraceConnectEnd(ctx, data)
}
}
}

// TracePrepareStart implements pgx.PrepareTracer.
func (t CompositeQueryTracer) TracePrepareStart(ctx context.Context, conn *pgx.Conn, data pgx.TracePrepareStartData) context.Context {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.PrepareTracer); ok {
ctx = tracer.TracePrepareStart(ctx, conn, data)
}
}

return ctx
}

// TracePrepareEnd implements pgx.PrepareTracer.
func (t CompositeQueryTracer) TracePrepareEnd(ctx context.Context, conn *pgx.Conn, data pgx.TracePrepareEndData) {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.PrepareTracer); ok {
tracer.TracePrepareEnd(ctx, conn, data)
}
}
}

// TraceQueryStart implements pgx.QueryTracer.
func (t CompositeQueryTracer) TraceQueryStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceQueryStartData) context.Context {
for _, tracer := range t.Tracers {
ctx = tracer.TraceQueryStart(ctx, conn, data)
}

return ctx
}

// TraceQueryEnd implements pgx.QueryTracer.
func (t CompositeQueryTracer) TraceQueryEnd(ctx context.Context, conn *pgx.Conn, data pgx.TraceQueryEndData) {
for _, tracer := range t.Tracers {
tracer.TraceQueryEnd(ctx, conn, data)
}
}

// TraceBatchStart implements pgx.BatchTracer.
func (t CompositeQueryTracer) TraceBatchStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceBatchStartData) context.Context {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.BatchTracer); ok {
ctx = tracer.TraceBatchStart(ctx, conn, data)
}
}

return ctx
}

// TraceBatchQuery implements pgx.BatchTracer.
func (t CompositeQueryTracer) TraceBatchQuery(ctx context.Context, conn *pgx.Conn, data pgx.TraceBatchQueryData) {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.BatchTracer); ok {
tracer.TraceBatchQuery(ctx, conn, data)
}
}
}

// TraceBatchEnd implements pgx.BatchTracer.
func (t CompositeQueryTracer) TraceBatchEnd(ctx context.Context, conn *pgx.Conn, data pgx.TraceBatchEndData) {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.BatchTracer); ok {
tracer.TraceBatchEnd(ctx, conn, data)
}
}
}

// TraceCopyFromStart implements pgx.CopyFromTracer.
func (t CompositeQueryTracer) TraceCopyFromStart(ctx context.Context, conn *pgx.Conn, data pgx.TraceCopyFromStartData) context.Context {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.CopyFromTracer); ok {
ctx = tracer.TraceCopyFromStart(ctx, conn, data)
}
}

return ctx
}

// TraceCopyFromEnd implements pgx.CopyFromTracer.
func (t CompositeQueryTracer) TraceCopyFromEnd(ctx context.Context, conn *pgx.Conn, data pgx.TraceCopyFromEndData) {
for _, item := range t.Tracers {
if tracer, ok := item.(pgx.CopyFromTracer); ok {
tracer.TraceCopyFromEnd(ctx, conn, data)
}
}
}

// Package testingadapter provides a logger that writes to a test or benchmark
// log.
package pgxtrace

import (
"context"
"fmt"

"github.com/jackc/pgx/v5/tracelog"
)

// TestingLogger interface defines the subset of testing.TB methods used by this
// adapter.
type TestingLogger interface {
Log(args ...any)
}

type Logger struct {
l TestingLogger
}

func NewLogger(l TestingLogger) *Logger {
return &Logger{l: l}
}

func (l *Logger) Log(ctx context.Context, level tracelog.LogLevel, msg string, data map[string]any) {
logArgs := make([]any, 0, 2+len(data))
logArgs = append(logArgs, level, msg)
for k, v := range data {
logArgs = append(logArgs, fmt.Sprintf("%s=%v", k, v))
}
l.l.Log(logArgs...)
}

```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository file or test is named. Start by reviewing the pgxpool.ParseConfig setup, config.ConnConfig.Tracer assignment, tracelog.TraceLog, and CustomLogger shown in the report, then reproduce the missing output. Done would mean identifying the configuration or usage issue and documenting a verified way to trace queries and connections.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, postgresql
Domain
databases, observability
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.