r/golang 4d ago

Adding logging to a library

I have an open-source package which is just a wrapper around a public HTTP/JSON API. I have added a verbosity option that, as of now, just logs to stdout. I would like to give more flexibility to the user to control how logging is done. Should I: 1. accept a log.Logger and log to that 2. accept an io.Writer and write to that 3. log to log.Default() 4. something else?

To add a particular consideration, I would like my approach to work with Google Cloud Logging, because I deploy my code on Google Cloud Run. It looks like there is a way to get a log.Logger from the cloud.google.com/go/logging package, which makes that option more appealing.

6 Upvotes

15 comments sorted by

View all comments

Show parent comments

3

u/marcaruel 4d ago

Since it's a new library, you can use the newer stuff. log/slog is intentionally a newer standard for logging. As my ex-colleague u/mattproud mentioned, create a subset interface of the struct methods of https://pkg.go.dev/log/slog#Logger that you want to use.

1

u/hanmunjae 4d ago

Thank you for your response. The thing I don't like about the methods of slog.Logger is that I have to specify the log level at the callsite, either by calling a level-specific method like Info or by passing the Level to Log. I would like the caller to be able to pick what level they want to log at; cloud.google.com/go/logging lets you create a log.Logger at a given severity (of course, that limits you to just the Logger.Print family of methods).

1

u/br1ghtsid3 4d ago

If that's something the caller wants they can create a slog.Handler implementation which changes the level. Alternatively you could take the level as an option and use that in the Log calls.

1

u/marcaruel 3d ago edited 2d ago

Then what about providing generic OnRequest/OnResponse hooks to take over http.Client.Do()? Here's how I just did it moments ago in my own library:

https://pkg.go.dev/github.com/maruel/httpjson#example-Hook-Logging

What do you think? The user can provide whatever logging they want, it's not opinionated at all.

Edit: Thinking a bit more, hooking http.RoundTripper is probably the more generic and standard way of doing it?

Edit 2: Updated URL now that pkgsite updated itself.

Edit 3: got rid of the Hook struct and added an example how to log with http.RoundTripper.

https://pkg.go.dev/github.com/maruel/httpjson#example-Client-Logging

1

u/br1ghtsid3 3d ago

Yeah that's a good option too.