4 ms·
It's fine for application logging but I have two gripes with slog: 1) If you're writing a library that can be used by many different applications and want to e
by peterldowns 1y ago
It's fine for application logging but I have two gripes with slog:
1) If you're writing a library that can be used by many different applications and want to emit logs, you'll still need to write a generic log interface with adapters for slog, zap, charmlog, etc. That the golang team refuses to bless a single interface for everyone to settle on both makes sense given their ideological standpoint on shipping interfaces and also causes endless mild annoyance and code duplication.
2) I believe it's still impossible to see the correct callsite in test logs when using slog as the logger. For more information, see https://github.com/neilotoole/slogt?tab=readme-ov-file#deficiency https://github.com/neilotoole/slogt?tab=readme-ov-file#defic.... It's possible I'm out of date here — please correct me if this is wrong, it's actually a much larger annoyance for me and one of the reasons I still use uber/zap or charmbracelet/log.
Overall, especially given that it performs worse than uber/zap and everyone has basically standardized on that and it provides essentially the same interface, I recommend using uber/zap instead.
EDIT: just to expand further, take a look at the recommended method of wrapping helper methods that call logs. Compare to the `t.Helper()` approach. And some previous discussion. Frustrating!
- https://pkg.go.dev/log/slog#example-package-Wrapping https://pkg.go.dev/log/slog#example-package-Wrapping
- https://github.com/golang/go/issues/59145#issuecomment-1477040044 https://github.com/golang/go/issues/59145#issuecomment-14770...
- aleksi 1y ago1) The idea is that your library should accept the slog logger and use it. The caller would create a logger with a handler that defines how log messages are handled. But there are problems with supported types; see my other comments. 2) It is improved in 1.25. See https://github.com/golang/go/issues/59928 https://github.com/golang/go/issues/59928 and https://pkg.go.dev/testing#T.Output https://pkg.go.dev/testing#T.Output. Now it is possible to update slogt to provide correct callsite – the stack depth should be the same.
- peterldowns 1y ago1) Right, but this is complicated and annoying. Imagine a world where you could just pass your existing logger in, because my library references an interface like `stdlib/logging.GenericLoggerInterface` and slog, zap, zerolog, etc. all implement that! Would be nice! 2) TIL about `T.Output`, thank you, that's great to know about. Still annoying and would be nice if the slog package showed an example of logging from tests with correct callsites. Golang gets so many things right about testing, so the fact that logging in tests is difficult really stands out and bothers me.
- phyrog 1y agoBut that is exactly what slog provides? The a unified interface that can be implemented by other logger libraries. Yes the Logger itself is not the interface, but the Handler it is backed by is.
- trenchpilgrim 1y agoWe switched to zerolog a while back and didn't look back.
- 9rx 1y ago> That the golang team refuses to bless a single interface for everyone to settle on Uh... https://pkg.go.dev/golang.org/x/exp/slog#Handler https://pkg.go.dev/golang.org/x/exp/slog#Handler If zap, charmlog, etc. don't provide conformance to the interface, that's not really on the Go team. It wouldn't be that hard to write your own adapter around your unidiomatic logger of choice if you're really stuck, though. This isn't an actual problem unless you think someone else owes you free labor for some reason.
- peterldowns 1y agoThat's close, but not what I meant — that's specific to this package, and is the interface for processing log records produced by a slog.Logger. What I mean is that there should be a single interface for Logging that is implemented by slog.Logger, uber/zap.Logger, etc. that library authors can use without needing to reinvent the wheel every time. For an example from one of my own libraries, see https://github.com/peterldowns/pgmigrate/blob/d3ecf8e4e8af87efcc79999d1068e8646a5e5cb0/logging.go#L31 https://github.com/peterldowns/pgmigrate/blob/d3ecf8e4e8af87...
- 9rx 1y ago> What I mean is that there should be a single interface for Logging that is implemented by slog.Logger, uber/zap.Logger, etc. There is: https://pkg.go.dev/golang.org/x/exp/slog#Handler https://pkg.go.dev/golang.org/x/exp/slog#Handler If, say, zap was conformant, you'd slog.New(zap.NewHandler()) or whatever and away you go. It seems the only problem here is that the logging packages you want to use are not following the blessed, idiomatic path. > For an example from one of my own libraries There are a lot of problem with that approach at scale. That might not matter for your pet projects, but slog also has to serve those who are pushing computers to their limits. Your idea didn't escape anyone.
- peterldowns 1y agoI know it didn't escape anyone; I'm explaining the downside to the choices made by the stdlib authors, from my perspective. When performance is a concern, people pick uber/zap.Logger or zerolog. When performance isn't a huge concern, slog is overly complicated and annoying. I believe you understand my complaint.
- arccy 1y agoThe blessed interface for libraries is to accept a slog.Logger. The blessed interface for logging backends is slog.Handler. Applications can then wire that up with a handler they like, for example zap: https://pkg.go.dev/go.uber.org/zap/exp/zapslog#Handler https://pkg.go.dev/go.uber.org/zap/exp/zapslog#Handler charm https://github.com/charmbracelet/log?tab=readme-ov-file#slog-handler https://github.com/charmbracelet/log?tab=readme-ov-file#slog...
- trenchpilgrim 1y agoI used slog.Logger for an OSS project and I will not do it again. The interface is terrible, and far more verbose and less expressive than something like Zap or zerolog. e.g. there's not really anything as good as zerolog's log.Dict() for dealing with complex structures.