jackc / jackc/pgx

slog compatible structured logging

Open
#1,582 9 comments 3 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
14.3k
Forks
1.1k
Avg merge
6d 9h
Merged PRs (30d)
11

Description

Hello & thanks for the awesome project!

I have recently been playing with *slog*, which is a new (currently experimental) structured logging interface for the Go programming language. In one of the upcoming Go releases it will be merged into the standard library.

Recommended resources:
* https://pkg.go.dev/golang.org/x/exp/slog
* https://www.youtube.com/watch?v=gd_Vyb5vEw0
* https://github.com/golang/go/issues/56345

The function signatures for `tracelog.QueryTracer.Log` and `slog.Log` are almost compatible:

```go
Log(ctx context.Context, level LogLevel, msg string, data map[string]any)
```
https://godocs.io/github.com/jackc/pgx/v5/tracelog#Logger

```go
func (l *Logger) Log(ctx context.Context, level Level, msg string, args ...any)
```
https://pkg.go.dev/golang.org/x/exp/slog#Logger.Log

It would be awesome if they were fully compatible, since then a `slog` Logger can be passed as-is to pgx/tracelog -- though I'm not sure if anything can be done about that at this point.

Alternatively, I came up with the following adapter for tracelog / slog:

```go
package adapter

import (
"context"

"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/tracelog"
"golang.org/x/exp/slog"
)

// This type implements the tracelog.Logger interface by wrapping a slog.Logger
// https://godocs.io/github.com/jackc/pgx/v5/tracelog
// https://godocs.io/github.com/jackc/pgx/v5#QueryTracer
// https://godocs.io/golang.org/x/exp/slog
type Logger struct {
slogger *slog.Logger
}

func NewTracerLogger(l *slog.Logger) pgx.QueryTracer {
return &tracelog.TraceLog{
Logger: &Logger{slogger: l},
LogLevel: tracelog.LogLevelTrace,
}
}

func (l *Logger) Log(ctx context.Context, level tracelog.LogLevel, msg string, data map[string]any) {
var attrs []slog.Attr
for k, v := range data {
attrs = append(attrs, slog.Any(k, v))
}
l.slogger.LogAttrs(ctx, translateLevel(level), msg, attrs...)
}

func translateLevel(level tracelog.LogLevel) slog.Level {
switch level {
case tracelog.LogLevelTrace:
return slog.LevelDebug
case tracelog.LogLevelDebug:
return slog.LevelDebug
case tracelog.LogLevelInfo:
return slog.LevelInfo
case tracelog.LogLevelWarn:
return slog.LevelWarn
case tracelog.LogLevelError:
return slog.LevelError
case tracelog.LogLevelNone:
return slog.LevelError
default:
return slog.LevelError
}
}
```

Since I'm not aware of all the best-practices regarding Go module structures, I'm not sure if this adapter should go into a separate repo, be part of the tracelog package, have it's own module but be part of the pgx repo etc.

Contributor guide

Open the contributing guide

Research direction

Start with the tracelog.Logger and tracelog.TraceLog APIs referenced in the issue, then compare their signatures with golang.org/x/exp/slog.Logger.Log. Determine whether direct compatibility is possible or whether an adapter is appropriate, including where it should live in the pgx module structure. Done means an agreed integration approach with its scope and placement defined.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
observability-sre
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.