From 39afdba29c11cf9a3f4e24d34a4734064453cd62 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 3 Jan 2024 15:49:13 +0100 Subject: [PATCH 1/3] dependencies: logr v1.4.1 This moves slog support into the main package. Go >1.18 is needed for generic type parameters. --- .github/workflows/test.yml | 4 ++-- examples/go.mod | 2 +- examples/go.sum | 4 ++-- go.mod | 4 ++-- go.sum | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b798c1b7..09e62ea0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ jobs: test: strategy: matrix: - go-version: [1.18, 1.19, 1.20, 1.21] + go-version: ["1.18", "1.19", "1.20", "1.21"] platform: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: @@ -27,7 +27,7 @@ jobs: - name: Install Go uses: actions/setup-go@v1 with: - go-version: 1.18 + go-version: 1.21 - name: Add GOBIN to PATH run: echo "PATH=$(go env GOPATH)/bin:$PATH" >>$GITHUB_ENV - name: Install dependencies diff --git a/examples/go.mod b/examples/go.mod index b4ef2a62..be4bff14 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -3,7 +3,7 @@ module k8s.io/klog/examples go 1.13 require ( - github.com/go-logr/logr v1.3.0 + github.com/go-logr/logr v1.4.1 github.com/go-logr/zapr v1.2.3 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b go.uber.org/goleak v1.1.12 diff --git a/examples/go.sum b/examples/go.sum index 96988baf..c3ac4096 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= diff --git a/go.mod b/go.mod index 15f54c27..c0a06788 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ module k8s.io/klog/v2 -go 1.13 +go 1.18 -require github.com/go-logr/logr v1.3.0 +require github.com/go-logr/logr v1.4.1 diff --git a/go.sum b/go.sum index 391a9f52..0934eaae 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= From 5d1d2d5088c081963c86742661d3ca562f01a506 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 3 Jan 2024 15:50:20 +0100 Subject: [PATCH 2/3] add SetSlogLogger This is syntactic sugar, but it's still useful because it hides logr from developers who only care about klog and slog. --- contextual_slog.go | 31 +++++++++++++++++++++ contextual_slog_example_test.go | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 contextual_slog.go create mode 100644 contextual_slog_example_test.go diff --git a/contextual_slog.go b/contextual_slog.go new file mode 100644 index 00000000..d3b56252 --- /dev/null +++ b/contextual_slog.go @@ -0,0 +1,31 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package klog + +import ( + "log/slog" + + "github.com/go-logr/logr" +) + +// SetSlogLogger reconfigures klog to log through the slog logger. The logger must not be nil. +func SetSlogLogger(logger *slog.Logger) { + SetLoggerWithOptions(logr.FromSlogHandler(logger.Handler()), ContextualLogger(true)) +} diff --git a/contextual_slog_example_test.go b/contextual_slog_example_test.go new file mode 100644 index 00000000..0c2ba41a --- /dev/null +++ b/contextual_slog_example_test.go @@ -0,0 +1,48 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package klog_test + +import ( + "log/slog" + "os" + + "k8s.io/klog/v2" +) + +func ExampleSetSlogLogger() { + state := klog.CaptureState() + defer state.Restore() + + handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ + ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr { + if a.Key == slog.TimeKey { + // Avoid non-deterministic output. + return slog.Attr{} + } + return a + }, + }) + logger := slog.New(handler) + klog.SetSlogLogger(logger) + klog.Info("hello world") + + // Output: + // level=INFO msg="hello world" +} From e4deee85f1cbc9ac407804b4a0fc1a38123b62f2 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 3 Jan 2024 15:56:36 +0100 Subject: [PATCH 3/3] slog: use main logr package instead of logr/slogr logr v1.4.0 moved the slog support functions in the main package and deprecated slogr. --- klogr_slog.go | 10 +++++----- klogr_slog_test.go | 17 +++++++++-------- textlogger/textlogger_slog.go | 8 ++++---- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/klogr_slog.go b/klogr_slog.go index f7bf7403..c77d7baa 100644 --- a/klogr_slog.go +++ b/klogr_slog.go @@ -25,7 +25,7 @@ import ( "strconv" "time" - "github.com/go-logr/logr/slogr" + "github.com/go-logr/logr" "k8s.io/klog/v2/internal/buffer" "k8s.io/klog/v2/internal/serialize" @@ -35,7 +35,7 @@ import ( func (l *klogger) Handle(ctx context.Context, record slog.Record) error { if logging.logger != nil { - if slogSink, ok := logging.logger.GetSink().(slogr.SlogSink); ok { + if slogSink, ok := logging.logger.GetSink().(logr.SlogSink); ok { // Let that logger do the work. return slogSink.Handle(ctx, record) } @@ -77,13 +77,13 @@ func slogOutput(file string, line int, now time.Time, err error, s severity.Seve buffer.PutBuffer(b) } -func (l *klogger) WithAttrs(attrs []slog.Attr) slogr.SlogSink { +func (l *klogger) WithAttrs(attrs []slog.Attr) logr.SlogSink { clone := *l clone.values = serialize.WithValues(l.values, sloghandler.Attrs2KVList(l.groups, attrs)) return &clone } -func (l *klogger) WithGroup(name string) slogr.SlogSink { +func (l *klogger) WithGroup(name string) logr.SlogSink { clone := *l if clone.groups != "" { clone.groups += "." + name @@ -93,4 +93,4 @@ func (l *klogger) WithGroup(name string) slogr.SlogSink { return &clone } -var _ slogr.SlogSink = &klogger{} +var _ logr.SlogSink = &klogger{} diff --git a/klogr_slog_test.go b/klogr_slog_test.go index b6431a71..d112b0fd 100644 --- a/klogr_slog_test.go +++ b/klogr_slog_test.go @@ -27,7 +27,8 @@ import ( "os" "time" - "github.com/go-logr/logr/slogr" + "github.com/go-logr/logr" + "k8s.io/klog/v2" internal "k8s.io/klog/v2/internal/buffer" ) @@ -71,7 +72,7 @@ func ExampleBackground_Slog() { internal.Pid = 123 logrLogger := klog.Background() - slogHandler := slogr.NewSlogHandler(logrLogger) + slogHandler := logr.ToSlogHandler(logrLogger) slogLogger := slog.New(slogHandler) // Note that -vmodule does not work when using the slog API because @@ -107,10 +108,10 @@ func ExampleBackground_Slog() { ) // Output: - // I1224 12:30:40.000000 123 klogr_slog_test.go:80] "A debug message" - // I1224 12:30:40.000000 123 klogr_slog_test.go:82] "An info message" - // W1224 12:30:40.000000 123 klogr_slog_test.go:83] "A warning" - // E1224 12:30:40.000000 123 klogr_slog_test.go:84] "An error" err="fake error" - // I1224 12:30:40.000000 123 klogr_slog_test.go:87] "Grouping" top.sub={"str":"abc","bool":true,"bottom":{"coordinates":{"X":-1,"Y":-2}}} top.duration="1s" top.pi=3.12 top.e=2.71 top.moreCoordinates={"X":100,"Y":200} - // I1224 12:30:40.000000 123 klogr_slog_test.go:103] "slog values" variables={"a":1,"b":2} duration="1s" coordinates={"X":100,"Y":200} + // I1224 12:30:40.000000 123 klogr_slog_test.go:81] "A debug message" + // I1224 12:30:40.000000 123 klogr_slog_test.go:83] "An info message" + // W1224 12:30:40.000000 123 klogr_slog_test.go:84] "A warning" + // E1224 12:30:40.000000 123 klogr_slog_test.go:85] "An error" err="fake error" + // I1224 12:30:40.000000 123 klogr_slog_test.go:88] "Grouping" top.sub={"str":"abc","bool":true,"bottom":{"coordinates":{"X":-1,"Y":-2}}} top.duration="1s" top.pi=3.12 top.e=2.71 top.moreCoordinates={"X":100,"Y":200} + // I1224 12:30:40.000000 123 klogr_slog_test.go:104] "slog values" variables={"a":1,"b":2} duration="1s" coordinates={"X":100,"Y":200} } diff --git a/textlogger/textlogger_slog.go b/textlogger/textlogger_slog.go index af0fab00..c888ef8a 100644 --- a/textlogger/textlogger_slog.go +++ b/textlogger/textlogger_slog.go @@ -23,7 +23,7 @@ import ( "context" "log/slog" - "github.com/go-logr/logr/slogr" + "github.com/go-logr/logr" "k8s.io/klog/v2/internal/serialize" "k8s.io/klog/v2/internal/sloghandler" @@ -33,13 +33,13 @@ func (l *tlogger) Handle(ctx context.Context, record slog.Record) error { return sloghandler.Handle(ctx, record, l.groups, l.printWithInfos) } -func (l *tlogger) WithAttrs(attrs []slog.Attr) slogr.SlogSink { +func (l *tlogger) WithAttrs(attrs []slog.Attr) logr.SlogSink { clone := *l clone.values = serialize.WithValues(l.values, sloghandler.Attrs2KVList(l.groups, attrs)) return &clone } -func (l *tlogger) WithGroup(name string) slogr.SlogSink { +func (l *tlogger) WithGroup(name string) logr.SlogSink { clone := *l if clone.groups != "" { clone.groups += "." + name @@ -49,4 +49,4 @@ func (l *tlogger) WithGroup(name string) slogr.SlogSink { return &clone } -var _ slogr.SlogSink = &tlogger{} +var _ logr.SlogSink = &tlogger{}