Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

options.Logger is incompatible to slog logger #898

Open
TLINDEN opened this issue Feb 10, 2025 · 5 comments
Open

options.Logger is incompatible to slog logger #898

TLINDEN opened this issue Feb 10, 2025 · 5 comments

Comments

@TLINDEN
Copy link

TLINDEN commented Feb 10, 2025

I am using the slog logger and wanted to enable the new Options.Logger feature, which fails:

lg := slog.Default()
opts.Logger = *lg
db, err := bolt.Open(db.Dbfile, 0600, opts)

Compilation fails:

cannot use *lg (variable of type slog.Logger) as bbolt.Logger value in assignment: slog.Logger does not implement bbolt.Logger (method Debug has pointer receiver)

So, in order to be able to use my existing logger setup, I'd have to implement a bolt.Logger wrapper around the slog logger.

I'd appreciate it, if slog would be supported directly.

best,
Tom

@ivanvc
Copy link
Member

ivanvc commented Feb 14, 2025

We covered this in the fortnightly etcd triage meeting. In #509, the decision was to implement a logger interface compatible with go.uber.org/zap.

I'm torn because implementing a bridge/wrapper struct for every existing logger doesn't make sense and may quickly become an issue. However, log/slog is part of Golang's stdlib.

The bridge/wrapper is pretty simple:

import (
        "fmt"
        "log/slog"

        bolt "go.etcd.io/bbolt"
)

type logger struct {
        *slog.Logger
}

func (l logger) Debug(v ...interface{})                   {}
func (l logger) Debugf(format string, v ...interface{})   { l.Logger.Debug(fmt.Sprintf(format, v...)) }
func (l logger) Error(v ...interface{})                   {}
func (l logger) Errorf(format string, v ...interface{})   { l.Logger.Error(fmt.Sprintf(format, v...)) }
func (l logger) Info(v ...interface{})                    {}
func (l logger) Infof(format string, v ...interface{})    { l.Logger.Info(fmt.Sprintf(format, v...)) }
func (l logger) Warning(v ...interface{})                 {}
func (l logger) Warningf(format string, v ...interface{}) { l.Logger.Warn(fmt.Sprintf(format, v...)) }
func (l logger) Fatal(v ...interface{})                   {}
func (l logger) Fatalf(format string, v ...interface{})   { l.Logger.Error(fmt.Sprintf(format, v...)) }
func (l logger) Panic(v ...interface{})                   {}
func (l logger) Panicf(format string, v ...interface{})   { l.Logger.Error(fmt.Sprintf(format, v...)) }

func main() {
        lg := logger{slog.Default()}
        db, err := bolt.Open("test.db", 0600, &bolt.Options{Logger: lg})
        ...
}

Note that we only use the *f (formatted) functions. So, the implementation for the functions that don't receive a format can be empty.

I believe it would make more sense to document rather than implement it. What do you think, @ahrtr?

@ahrtr
Copy link
Member

ahrtr commented Feb 14, 2025

We don't want to manage any specific logger, nor their configuration. It's the reason why we only expose an interface.

Also exp/slog was experimental when we started to add logger into bbolt. But it's part of the golang std lib (starting from go1.21) now.

It's definitely better to enhance the document at least at https://pkg.go.dev/go.etcd.io/bbolt@v1.4.0#Logger.

If the community pushes hard, then I I do not object to adding thin wrappers for log/slog and go.uber.org/zap into bbolt repo, and expose interfaces something like WithSLog(...), WithUberLog(...).

@TLINDEN
Copy link
Author

TLINDEN commented Feb 14, 2025

Here's one vote for it ;)

@ahrtr
Copy link
Member

ahrtr commented Feb 14, 2025

Here's one vote for it ;)

Are you voting for below comment? :)

If the community pushes hard, then I I do not object to adding thin wrappers for log/slog and go.uber.org/zap into bbolt repo, and expose interfaces something like WithSLog(...), WithUberLog(...).

@TLINDEN
Copy link
Author

TLINDEN commented Feb 17, 2025

I did but to be honest, I followed the suggestion here and just implemented the logger interface. It's ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants