go log/slog: logger 丢弃了来自处理器的错误,

dsf9zpds  于 10个月前  发布在  Go
关注(0)|答案(2)|浏览(87)

Go版本
go版本 go1.21.0 darwin/arm64

go env 在你的模块/工作区中的输出:

  1. GO111MODULE=''
  2. GOARCH='arm64'
  3. GOBIN=''
  4. GOCACHE='/Users/s.hajyahya/Library/Caches/go-build'
  5. GOENV='/Users/s.hajyahya/Library/Application Support/go/env'
  6. GOEXE=''
  7. GOEXPERIMENT=''
  8. GOFLAGS=''
  9. GOHOSTARCH='arm64'
  10. GOHOSTOS='darwin'
  11. GOINSECURE=''
  12. GOMODCACHE='/Users/s.hajyahya/go/pkg/mod'
  13. GONOPROXY=''
  14. GONOSUMDB=''
  15. GOOS='darwin'
  16. GOPATH='/Users/s.hajyahya/go'
  17. GOPRIVATE=''
  18. GOPROXY='https://proxy.golang.org,direct'
  19. GOROOT='/usr/local/go'
  20. GOSUMDB='sum.golang.org'
  21. GOTMPDIR=''
  22. GOTOOLCHAIN='auto'
  23. GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
  24. GOVCS=''
  25. GOVERSION='go1.21.0'
  26. GCCGO='gccgo'
  27. AR='ar'
  28. CC='clang'
  29. CXX='clang++'
  30. CGO_ENABLED='1'
  31. GOMOD='/Users/s.hajyahya/dev/stuff/ssh/go.mod'
  32. GOWORK=''
  33. CGO_CFLAGS='-O2 -g'
  34. CGO_CPPFLAGS=''
  35. CGO_CXXFLAGS='-O2 -g'
  36. CGO_FFLAGS='-O2 -g'
  37. CGO_LDFLAGS='-O2 -g'
  38. PKG_CONFIG='pkg-config'
  39. GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/_w/y7hb861d42z_drrgmkk7pb440000gp/T/go-build182075280=/tmp/go-build -gno-record-gcc-switches -fno-common'

你做了什么?

  1. func TestXxx(t *testing.T) {
  2. t.Error("log")
  3. h := new(remoteHandler)
  4. lg := slog.New(h)
  5. lg.Info("example")
  6. }
  7. type remoteHandler struct {
  8. }
  9. func (h *remoteHandler) Enabled(_ context.Context, level slog.Level) bool {
  10. return true
  11. }
  12. // WithAttrs returns a new [TextHandler] whose attributes consists
  13. // of h's attributes followed by attrs.
  14. func (h *remoteHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
  15. return nil
  16. }
  17. func (h *remoteHandler) WithGroup(name string) slog.Handler {
  18. return nil
  19. }
  20. func (h *remoteHandler) Handle(_ context.Context, r slog.Record) error {
  21. err := errors.New("any remote error")
  22. fmt.Println(err)
  23. return err
  24. }

你看到了什么发生?

日志记录器忽略了处理程序的错误,并且有一个方法可以显式设置错误处理机制。
参见 https://github.com/golang/go/blob/master/src/log/slog/logger.go#L257

你期望看到什么?

Slog通过采用前端和后端设计引入了一种哲学,其中日志记录器作为前端,处理程序作为后端。然而,后端/处理程序可能需要将日志写入远程日志记录器,因此处理这些错误对于用户来说至关重要,以了解为什么某些日志没有被发送或记录,而不管处理程序在做什么。尽管默认情况下前端/日志记录器可以通过忽略这些错误来接受这些错误,但用户至少应该允许自己设置错误处理程序。
当使用stdlib log时,没有办法设置错误处理程序,但这是可以接受的,因为该日志包只采用了不同的设计。如果用户打算处理错误,他们可以将自定义错误处理程序 Package 到io writer中。然而,将slog处理程序 Package 并将其传递给slog被认为是过度使用,因为它与slog的设计和哲学不兼容。
查看其他包,如flag,它提供了像continue或panic这样的错误处理选项,以及httputil,其中代理允许通过显式设置函数来处理错误,这将有助于更新文档以澄清slog日志记录器忽略处理程序的错误(如果此信息尚未出现)。此外,向用户公开一个错误处理函数以便显式设置它也是有益的。
这可能需要从错误报告转换为提案,但在此将其移动到提案板之前在这里开始讨论可能会有所帮助。

  1. func TestXxx(t *testing.T) {
  2. t.Error("log")
  3. h := new(remoteHandler)
  4. lg := slog.New(h).WithErrorHandler(func(slog.Record, error){
  5. // handle error.
  6. })
  7. lg.Info("example")
  8. }
  9. type remoteHandler struct {
  10. }
  11. func (h *remoteHandler) Enabled(_ context.Context, level slog.Level) bool {
  12. return true
  13. }
  14. // WithAttrs returns a new [TextHandler] whose attributes consists
  15. // of h's attributes followed by attrs.
  16. func (h *remoteHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
  17. return nil
  18. }
  19. func (h *remoteHandler) WithGroup(name string) slog.Handler {
  20. return nil
  21. }
  22. func (h *remoteHandler) Handle(_ context.Context, r slog.Record) error {
  23. err := errors.New("any remote error")
  24. fmt.Println(err)
  25. return err
  26. }
lhcgjxsq

lhcgjxsq1#

CC @jba

s71maibg

s71maibg2#

然而,将slog处理器进行 Package 并传递给slog被认为是过度设计,因为它与slog的设计和哲学不兼容。相反,一个报告错误的 Package 处理器正是我们所期望的。我们应该在文档中更好地解释这一点,也许可以提供一个示例。我认为一旦我们这样做了,编写这样一个处理器就会变得足够容易,我们不需要向包中添加任何API。

相关问题