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

Race in slog text handler #50450

Closed
rosstimothy opened this issue Dec 19, 2024 · 0 comments · Fixed by #50451
Closed

Race in slog text handler #50450

rosstimothy opened this issue Dec 19, 2024 · 0 comments · Fixed by #50451
Assignees
Labels

Comments

@rosstimothy
Copy link
Contributor

CI caught a race in the slog text handlers group handling:

https://github.com/gravitational/teleport/actions/runs/12410421297/job/34646019797?pr=50429

==================
WARNING: DATA RACE
Read at 0x00c0053b65b0 by goroutine 16048:
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).appendAttr()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:201 +0x11f9
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).Handle.func2()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:378 +0x124
  log/slog.Record.Attrs()
      /opt/go/src/log/slog/record.go:84 +0xd2
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).Handle()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:372 +0x1664
  log/slog.(*Logger).log()
      /opt/go/src/log/slog/logger.go:257 +0x228
  log/slog.(*Logger).InfoContext()
      /opt/go/src/log/slog/logger.go:215 +0xc44
  github.com/gravitational/teleport/lib/httplib/reverseproxy.(*roundTripperWithLogger).RoundTrip()
      /__w/teleport/teleport/lib/httplib/reverseproxy/reverse_proxy.go:228 +0x405
  net/http/httputil.(*ReverseProxy).ServeHTTP()
      /opt/go/src/net/http/httputil/reverseproxy.go:481 +0x1668
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).listResourcesList()
      /__w/teleport/teleport/lib/kube/proxy/resource_list.go:117 +0x274
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).listResources()
      /__w/teleport/teleport/lib/kube/proxy/resource_list.go:91 +0xba7
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).catchAll()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:2096 +0x1753
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).catchAll-fm()
      <autogenerated>:1 +0x64
  github.com/gravitational/teleport/lib/kube/proxy.NewForwarder.(*Forwarder).withAuthStd.func4()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:597 +0x5e1
  github.com/gravitational/teleport/lib/kube/proxy.NewForwarder.(*Forwarder).withAuthStd.MakeStdHandlerWithErrorWriter.func6()
      /__w/teleport/teleport/lib/httplib/httplib.go:146 +0x82
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/julienschmidt/httprouter.(*Router).ServeHTTP()
      /go/pkg/mod/github.com/gravitational/httprouter@v1.3.1-0.20220408074523-c876c5e705a5/router.go:460 +0xda1
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerResponseSize.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:296 +0xee
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerCounter.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:147 +0xe5
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerDuration.func2()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:109 +0xd2
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/gravitational/teleport/lib/kube/proxy.instrumentHTTPHandlerWithPrometheus.InstrumentHandlerInFlight.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:60 +0x104
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176 +0x1afb
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65 +0x67
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).ServeHTTP()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:417 +0x63
  github.com/gravitational/teleport/lib/auth.(*Middleware).ServeHTTP()
      /__w/teleport/teleport/lib/auth/middleware.go:804 +0xa17
  github.com/gravitational/teleport/lib/limiter/internal/ratelimit.(*TokenLimiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/internal/ratelimit/ratelimit.go:106 +0x315
  github.com/gravitational/teleport/lib/limiter.(*RateLimiter).ServeHTTP()
      <autogenerated>:1 +0x64
  github.com/gravitational/teleport/lib/limiter.(*ConnectionsLimiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/connlimiter.go:82 +0x386
  github.com/gravitational/teleport/lib/limiter.(*Limiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/limiter.go:82 +0x53
  github.com/gravitational/teleport/lib/httplib.MakeTracingHandler.func1()
      /__w/teleport/teleport/lib/httplib/httplib.go:103 +0x281
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176 +0x1afb
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65 +0x67
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  net/http.serverHandler.ServeHTTP()
      /opt/go/src/net/http/server.go:3210 +0x2a1
  net/http.initALPNRequest.ServeHTTP()
      /opt/go/src/net/http/server.go:3819 +0x35e
  net/http.(*initALPNRequest).ServeHTTP()
      <autogenerated>:1 +0x7b
  net/http.Handler.ServeHTTP-fm()
      <autogenerated>:1 +0x67
  golang.org/x/net/http2.(*serverConn).runHandler()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2458 +0x253
  golang.org/x/net/http2.(*serverConn).scheduleHandler.gowrap1()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2392 +0x5d

Previous write at 0x00c0053b65b0 by goroutine 16054:
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).appendAttr()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:218 +0x185a
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).Handle.func2()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:378 +0x124
  log/slog.Record.Attrs()
      /opt/go/src/log/slog/record.go:84 +0xd2
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).Handle()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:372 +0x1664
  log/slog.(*Logger).log()
      /opt/go/src/log/slog/logger.go:257 +0x228
  log/slog.(*Logger).InfoContext()
      /opt/go/src/log/slog/logger.go:215 +0xc44
  github.com/gravitational/teleport/lib/httplib/reverseproxy.(*roundTripperWithLogger).RoundTrip()
      /__w/teleport/teleport/lib/httplib/reverseproxy/reverse_proxy.go:228 +0x405
  net/http/httputil.(*ReverseProxy).ServeHTTP()
      /opt/go/src/net/http/httputil/reverseproxy.go:481 +0x1668
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).listResourcesList()
      /__w/teleport/teleport/lib/kube/proxy/resource_list.go:117 +0x274
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).listResources()
      /__w/teleport/teleport/lib/kube/proxy/resource_list.go:91 +0xba7
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).catchAll()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:2096 +0x1753
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).catchAll-fm()
      <autogenerated>:1 +0x64
  github.com/gravitational/teleport/lib/kube/proxy.NewForwarder.(*Forwarder).withAuthStd.func4()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:597 +0x5e1
  github.com/gravitational/teleport/lib/kube/proxy.NewForwarder.(*Forwarder).withAuthStd.MakeStdHandlerWithErrorWriter.func6()
      /__w/teleport/teleport/lib/httplib/httplib.go:146 +0x82
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/julienschmidt/httprouter.(*Router).ServeHTTP()
      /go/pkg/mod/github.com/gravitational/httprouter@v1.3.1-0.20220408074523-c876c5e705a5/router.go:460 +0xda1
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerResponseSize.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:296 +0xee
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerCounter.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:147 +0xe5
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerDuration.func2()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:109 +0xd2
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/gravitational/teleport/lib/kube/proxy.instrumentHTTPHandlerWithPrometheus.InstrumentHandlerInFlight.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:60 +0x104
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176 +0x1afb
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65 +0x67
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).ServeHTTP()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:417 +0x63
  github.com/gravitational/teleport/lib/auth.(*Middleware).ServeHTTP()
      /__w/teleport/teleport/lib/auth/middleware.go:804 +0xa17
  github.com/gravitational/teleport/lib/limiter/internal/ratelimit.(*TokenLimiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/internal/ratelimit/ratelimit.go:106 +0x315
  github.com/gravitational/teleport/lib/limiter.(*RateLimiter).ServeHTTP()
      <autogenerated>:1 +0x64
  github.com/gravitational/teleport/lib/limiter.(*ConnectionsLimiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/connlimiter.go:82 +0x386
  github.com/gravitational/teleport/lib/limiter.(*Limiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/limiter.go:82 +0x53
  github.com/gravitational/teleport/lib/httplib.MakeTracingHandler.func1()
      /__w/teleport/teleport/lib/httplib/httplib.go:103 +0x281
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176 +0x1afb
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65 +0x67
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  net/http.serverHandler.ServeHTTP()
      /opt/go/src/net/http/server.go:3210 +0x2a1
  net/http.initALPNRequest.ServeHTTP()
      /opt/go/src/net/http/server.go:3819 +0x35e
  net/http.(*initALPNRequest).ServeHTTP()
      <autogenerated>:1 +0x7b
  net/http.Handler.ServeHTTP-fm()
      <autogenerated>:1 +0x67
  golang.org/x/net/http2.(*serverConn).runHandler()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2458 +0x253
  golang.org/x/net/http2.(*serverConn).scheduleHandler.gowrap1()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2392 +0x5d

Goroutine 16048 (running) created at:
  golang.org/x/net/http2.(*serverConn).scheduleHandler()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2392 +0x28a
  golang.org/x/net/http2.(*serverConn).processHeaders()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2114 +0xcea
  golang.org/x/net/http2.(*serverConn).processFrame()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1610 +0x2a4
  golang.org/x/net/http2.(*serverConn).processFrameFromReader()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1548 +0x304
  golang.org/x/net/http2.(*serverConn).serve()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1003 +0x19e4
  golang.org/x/net/http2.(*Server).serveConn()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:566 +0x1ba4
  golang.org/x/net/http2.(*Server).ServeConn()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:425 +0x1e8
  golang.org/x/net/http2.ConfigureServer.func1()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:325 +0xe6
  golang.org/x/net/http2.ConfigureServer.func2()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:333 +0x62
  net/http.(*conn).serve()
      /opt/go/src/net/http/server.go:2000 +0xc21
  net/http.(*Server).Serve.gowrap3()
      /opt/go/src/net/http/server.go:3360 +0x4f

Goroutine 16054 (running) created at:
  golang.org/x/net/http2.(*serverConn).scheduleHandler()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2392 +0x28a
  golang.org/x/net/http2.(*serverConn).processHeaders()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2114 +0xcea
  golang.org/x/net/http2.(*serverConn).processFrame()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1610 +0x2a4
  golang.org/x/net/http2.(*serverConn).processFrameFromReader()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1548 +0x304
  golang.org/x/net/http2.(*serverConn).serve()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1003 +0x19e4
  golang.org/x/net/http2.(*Server).serveConn()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:566 +0x1ba4
  golang.org/x/net/http2.(*Server).ServeConn()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:425 +0x1e8
  golang.org/x/net/http2.ConfigureServer.func1()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:325 +0xe6
  golang.org/x/net/http2.ConfigureServer.func2()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:333 +0x62
  net/http.(*conn).serve()
      /opt/go/src/net/http/server.go:2000 +0xc21
  net/http.(*Server).Serve.gowrap3()
      /opt/go/src/net/http/server.go:3360 +0x4f
==================
==================
WARNING: DATA RACE
Write at 0x00c0097d2c48 by goroutine 16048:
  runtime.slicecopy()
      /opt/go/src/runtime/slice.go:355 +0x0
  fmt.Append()
      /opt/go/src/fmt/print.go:290 +0x104
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).appendAttr()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:211 +0x804
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).Handle.func2()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:378 +0x124
  log/slog.Record.Attrs()
      /opt/go/src/log/slog/record.go:84 +0xd2
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).Handle()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:372 +0x1664
  log/slog.(*Logger).log()
      /opt/go/src/log/slog/logger.go:257 +0x228
  log/slog.(*Logger).InfoContext()
      /opt/go/src/log/slog/logger.go:215 +0xc44
  github.com/gravitational/teleport/lib/httplib/reverseproxy.(*roundTripperWithLogger).RoundTrip()
      /__w/teleport/teleport/lib/httplib/reverseproxy/reverse_proxy.go:228 +0x405
  net/http/httputil.(*ReverseProxy).ServeHTTP()
      /opt/go/src/net/http/httputil/reverseproxy.go:481 +0x1668
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).listResourcesList()
      /__w/teleport/teleport/lib/kube/proxy/resource_list.go:117 +0x274
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).listResources()
      /__w/teleport/teleport/lib/kube/proxy/resource_list.go:91 +0xba7
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).catchAll()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:2096 +0x1753
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).catchAll-fm()
      <autogenerated>:1 +0x64
  github.com/gravitational/teleport/lib/kube/proxy.NewForwarder.(*Forwarder).withAuthStd.func4()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:597 +0x5e1
  github.com/gravitational/teleport/lib/kube/proxy.NewForwarder.(*Forwarder).withAuthStd.MakeStdHandlerWithErrorWriter.func6()
      /__w/teleport/teleport/lib/httplib/httplib.go:146 +0x82
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/julienschmidt/httprouter.(*Router).ServeHTTP()
      /go/pkg/mod/github.com/gravitational/httprouter@v1.3.1-0.20220408074523-c876c5e705a5/router.go:460 +0xda1
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerResponseSize.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:296 +0xee
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerCounter.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:147 +0xe5
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerDuration.func2()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:109 +0xd2
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/gravitational/teleport/lib/kube/proxy.instrumentHTTPHandlerWithPrometheus.InstrumentHandlerInFlight.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:60 +0x104
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176 +0x1afb
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65 +0x67
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).ServeHTTP()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:417 +0x63
  github.com/gravitational/teleport/lib/auth.(*Middleware).ServeHTTP()
      /__w/teleport/teleport/lib/auth/middleware.go:804 +0xa17
  github.com/gravitational/teleport/lib/limiter/internal/ratelimit.(*TokenLimiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/internal/ratelimit/ratelimit.go:106 +0x315
  github.com/gravitational/teleport/lib/limiter.(*RateLimiter).ServeHTTP()
      <autogenerated>:1 +0x64
  github.com/gravitational/teleport/lib/limiter.(*ConnectionsLimiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/connlimiter.go:82 +0x386
  github.com/gravitational/teleport/lib/limiter.(*Limiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/limiter.go:82 +0x53
  github.com/gravitational/teleport/lib/httplib.MakeTracingHandler.func1()
      /__w/teleport/teleport/lib/httplib/httplib.go:103 +0x281
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176 +0x1afb
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65 +0x67
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  net/http.serverHandler.ServeHTTP()
      /opt/go/src/net/http/server.go:3210 +0x2a1
  net/http.initALPNRequest.ServeHTTP()
      /opt/go/src/net/http/server.go:3819 +0x35e
  net/http.(*initALPNRequest).ServeHTTP()
      <autogenerated>:1 +0x7b
  net/http.Handler.ServeHTTP-fm()
      <autogenerated>:1 +0x67
  golang.org/x/net/http2.(*serverConn).runHandler()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2458 +0x253
  golang.org/x/net/http2.(*serverConn).scheduleHandler.gowrap1()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2392 +0x5d

Previous write at 0x00c0097d2c48 by goroutine 16054:
  runtime.slicecopy()
      /opt/go/src/runtime/slice.go:355 +0x0
  fmt.Append()
      /opt/go/src/fmt/print.go:290 +0x104
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).appendAttr()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:211 +0x804
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).Handle.func2()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:378 +0x124
  log/slog.Record.Attrs()
      /opt/go/src/log/slog/record.go:84 +0xd2
  github.com/gravitational/teleport/lib/utils/log.(*SlogTextHandler).Handle()
      /__w/teleport/teleport/lib/utils/log/slog_handler.go:372 +0x1664
  log/slog.(*Logger).log()
      /opt/go/src/log/slog/logger.go:257 +0x228
  log/slog.(*Logger).InfoContext()
      /opt/go/src/log/slog/logger.go:215 +0xc44
  github.com/gravitational/teleport/lib/httplib/reverseproxy.(*roundTripperWithLogger).RoundTrip()
      /__w/teleport/teleport/lib/httplib/reverseproxy/reverse_proxy.go:228 +0x405
  net/http/httputil.(*ReverseProxy).ServeHTTP()
      /opt/go/src/net/http/httputil/reverseproxy.go:481 +0x1668
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).listResourcesList()
      /__w/teleport/teleport/lib/kube/proxy/resource_list.go:117 +0x274
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).listResources()
      /__w/teleport/teleport/lib/kube/proxy/resource_list.go:91 +0xba7
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).catchAll()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:2096 +0x1753
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).catchAll-fm()
      <autogenerated>:1 +0x64
  github.com/gravitational/teleport/lib/kube/proxy.NewForwarder.(*Forwarder).withAuthStd.func4()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:597 +0x5e1
  github.com/gravitational/teleport/lib/kube/proxy.NewForwarder.(*Forwarder).withAuthStd.MakeStdHandlerWithErrorWriter.func6()
      /__w/teleport/teleport/lib/httplib/httplib.go:146 +0x82
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/julienschmidt/httprouter.(*Router).ServeHTTP()
      /go/pkg/mod/github.com/gravitational/httprouter@v1.3.1-0.20220408074523-c876c5e705a5/router.go:460 +0xda1
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerResponseSize.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:296 +0xee
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerCounter.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:147 +0xe5
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerDuration.func2()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:109 +0xd2
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/gravitational/teleport/lib/kube/proxy.instrumentHTTPHandlerWithPrometheus.InstrumentHandlerInFlight.func1()
      /go/pkg/mod/github.com/prometheus/client_golang@v1.20.5/prometheus/promhttp/instrument_server.go:60 +0x104
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176 +0x1afb
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65 +0x67
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  github.com/gravitational/teleport/lib/kube/proxy.(*Forwarder).ServeHTTP()
      /__w/teleport/teleport/lib/kube/proxy/forwarder.go:417 +0x63
  github.com/gravitational/teleport/lib/auth.(*Middleware).ServeHTTP()
      /__w/teleport/teleport/lib/auth/middleware.go:804 +0xa17
  github.com/gravitational/teleport/lib/limiter/internal/ratelimit.(*TokenLimiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/internal/ratelimit/ratelimit.go:106 +0x315
  github.com/gravitational/teleport/lib/limiter.(*RateLimiter).ServeHTTP()
      <autogenerated>:1 +0x64
  github.com/gravitational/teleport/lib/limiter.(*ConnectionsLimiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/connlimiter.go:82 +0x386
  github.com/gravitational/teleport/lib/limiter.(*Limiter).ServeHTTP()
      /__w/teleport/teleport/lib/limiter/limiter.go:82 +0x53
  github.com/gravitational/teleport/lib/httplib.MakeTracingHandler.func1()
      /__w/teleport/teleport/lib/httplib/httplib.go:103 +0x281
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176 +0x1afb
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1()
      /go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65 +0x67
  net/http.HandlerFunc.ServeHTTP()
      /opt/go/src/net/http/server.go:2220 +0x47
  net/http.serverHandler.ServeHTTP()
      /opt/go/src/net/http/server.go:3210 +0x2a1
  net/http.initALPNRequest.ServeHTTP()
      /opt/go/src/net/http/server.go:3819 +0x35e
  net/http.(*initALPNRequest).ServeHTTP()
      <autogenerated>:1 +0x7b
  net/http.Handler.ServeHTTP-fm()
      <autogenerated>:1 +0x67
  golang.org/x/net/http2.(*serverConn).runHandler()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2458 +0x253
  golang.org/x/net/http2.(*serverConn).scheduleHandler.gowrap1()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2392 +0x5d

Goroutine 16048 (running) created at:
  golang.org/x/net/http2.(*serverConn).scheduleHandler()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2392 +0x28a
  golang.org/x/net/http2.(*serverConn).processHeaders()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2114 +0xcea
  golang.org/x/net/http2.(*serverConn).processFrame()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1610 +0x2a4
  golang.org/x/net/http2.(*serverConn).processFrameFromReader()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1548 +0x304
  golang.org/x/net/http2.(*serverConn).serve()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1003 +0x19e4
  golang.org/x/net/http2.(*Server).serveConn()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:566 +0x1ba4
  golang.org/x/net/http2.(*Server).ServeConn()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:425 +0x1e8
  golang.org/x/net/http2.ConfigureServer.func1()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:325 +0xe6
  golang.org/x/net/http2.ConfigureServer.func2()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:333 +0x62
  net/http.(*conn).serve()
      /opt/go/src/net/http/server.go:2000 +0xc21
  net/http.(*Server).Serve.gowrap3()
      /opt/go/src/net/http/server.go:3360 +0x4f

Goroutine 16054 (running) created at:
  golang.org/x/net/http2.(*serverConn).scheduleHandler()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2392 +0x28a
  golang.org/x/net/http2.(*serverConn).processHeaders()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:2114 +0xcea
  golang.org/x/net/http2.(*serverConn).processFrame()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1610 +0x2a4
  golang.org/x/net/http2.(*serverConn).processFrameFromReader()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1548 +0x304
  golang.org/x/net/http2.(*serverConn).serve()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:1003 +0x19e4
  golang.org/x/net/http2.(*Server).serveConn()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:566 +0x1ba4
  golang.org/x/net/http2.(*Server).ServeConn()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:425 +0x1e8
  golang.org/x/net/http2.ConfigureServer.func1()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:325 +0xe6
  golang.org/x/net/http2.ConfigureServer.func2()
      /go/pkg/mod/golang.org/x/net@v0.31.0/http2/server.go:333 +0x62
  net/http.(*conn).serve()
      /opt/go/src/net/http/server.go:2000 +0xc21
  net/http.(*Server).Serve.gowrap3()
      /opt/go/src/net/http/server.go:3360 +0x4f
==================
@rosstimothy rosstimothy self-assigned this Dec 19, 2024
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 19, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
github-merge-queue bot pushed a commit that referenced this issue Dec 20, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 20, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 20, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 20, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

```
rosstimothy added a commit that referenced this issue Dec 20, 2024
Closes #50450.

This updates our custom slog text handler to take heavier
inspiration from the slog.TextHandler. A variant of handleState
used by the slog.TextHandler has been vendored and modified to
produce the same output as our custom logrus formatter. Offloading
formatting from the SlogTextHandler directly to handleState prevents
the race caused in #50450.

Additionally, some quality of life improvements were added by
moving some code around to reduce file sizes and better define
what belongs in a file.

Benchmarks indicate that the changes here don't move the needle
much.

```
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils/log
cpu: Apple M2 Pro
                               │   old.txt    │              new.txt               │
                               │    sec/op    │   sec/op     vs base               │
Formatter/logrus/text-12         8.665µ ± 16%   8.187µ ± 9%       ~ (p=0.280 n=10)
Formatter/logrus/json-12         8.879µ ±  2%   8.820µ ± 1%       ~ (p=0.089 n=10)
Formatter/slog/default_text-12   3.936µ ±  3%   3.946µ ± 4%       ~ (p=0.839 n=10)
Formatter/slog/text-12           3.789µ ±  2%   3.431µ ± 1%  -9.45% (p=0.000 n=10)
Formatter/slog/default_json-12   3.005µ ±  4%   3.032µ ± 3%       ~ (p=0.739 n=10)
Formatter/slog/json-12           3.029µ ±  6%   3.022µ ± 1%       ~ (p=0.381 n=10)
geomean                          4.675µ         4.557µ       -2.52%

                               │   old.txt    │                new.txt                │
                               │     B/op     │     B/op      vs base                 │
Formatter/logrus/text-12         5.936Ki ± 0%   5.936Ki ± 0%       ~ (p=0.752 n=10)
Formatter/logrus/json-12         6.212Ki ± 0%   6.211Ki ± 0%       ~ (p=0.752 n=10)
Formatter/slog/default_text-12   2.534Ki ± 0%   2.534Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           2.144Ki ± 0%   2.167Ki ± 0%  +1.09% (p=0.000 n=10)
Formatter/slog/default_json-12   2.448Ki ± 0%   2.448Ki ± 0%       ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           2.318Ki ± 0%   2.318Ki ± 0%       ~ (p=1.000 n=10) ¹
geomean                          3.231Ki        3.236Ki       +0.18%
¹ all samples are equal

                               │  old.txt   │               new.txt                │
                               │ allocs/op  │ allocs/op   vs base                  │
Formatter/logrus/text-12         54.00 ± 0%   54.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/logrus/json-12         76.00 ± 0%   76.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/default_text-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/text-12           52.00 ± 0%   33.00 ± 0%  -36.54% (p=0.000 n=10)
Formatter/slog/default_json-12   41.00 ± 0%   41.00 ± 0%        ~ (p=1.000 n=10) ¹
Formatter/slog/json-12           42.00 ± 0%   42.00 ± 0%        ~ (p=1.000 n=10) ¹
geomean                          49.70        46.07        -7.30%
¹ all samples are equal

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

Successfully merging a pull request may close this issue.

1 participant