From 35f338841a5869188af00d184f4273454ef64b97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 08:55:30 +0000 Subject: [PATCH] Bump code.cloudfoundry.org/lager/v3 from 3.0.2 to 3.0.3 Bumps [code.cloudfoundry.org/lager/v3](https://github.com/cloudfoundry/lager) from 3.0.2 to 3.0.3. - [Commits](https://github.com/cloudfoundry/lager/compare/v3.0.2...v3.0.3) --- updated-dependencies: - dependency-name: code.cloudfoundry.org/lager/v3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 4 +- go.sum | 8 +- .../code.cloudfoundry.org/lager/v3/README.md | 24 +++ .../code.cloudfoundry.org/lager/v3/handler.go | 162 ++++++++++++++++++ .../lager/v3/slog_sink.go | 63 +++++++ vendor/modules.txt | 4 +- 6 files changed, 257 insertions(+), 8 deletions(-) create mode 100644 vendor/code.cloudfoundry.org/lager/v3/handler.go create mode 100644 vendor/code.cloudfoundry.org/lager/v3/slog_sink.go diff --git a/go.mod b/go.mod index 19625b9d..ab916669 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( code.cloudfoundry.org/bbs v0.0.0-20230406145249-41bd09f9f0ca code.cloudfoundry.org/clock v1.1.0 code.cloudfoundry.org/debugserver v0.0.0-20230329140605-8c21649a9a42 - code.cloudfoundry.org/lager/v3 v3.0.2 + code.cloudfoundry.org/lager/v3 v3.0.3 code.cloudfoundry.org/localip v0.0.0-20230406154046-f137f65d303d code.cloudfoundry.org/locket v0.0.0-20230406154009-5e8522d975d2 code.cloudfoundry.org/runtimeschema v0.0.0-20230323223330-5366865eed76 @@ -37,7 +37,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect - github.com/openzipkin/zipkin-go v0.4.1 // indirect + github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/square/certstrap v1.3.0 // indirect github.com/tedsuo/rata v1.0.0 // indirect diff --git a/go.sum b/go.sum index 12e6ba29..360f22a9 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ code.cloudfoundry.org/go-diodes v0.0.0-20220325013804-800fb6f70e2f h1:BMwVyadJ0d code.cloudfoundry.org/go-diodes v0.0.0-20220325013804-800fb6f70e2f/go.mod h1:cCrRt/O3uipyXfV4hZsKe5WyRNgFTgiMHnwAQqFlNjM= code.cloudfoundry.org/go-loggregator/v8 v8.0.5 h1:p1rrGxTwUqLjlUVtbjTAvKOSGNmPuBja8LeQOQgRrBc= code.cloudfoundry.org/go-loggregator/v8 v8.0.5/go.mod h1:mLlJ1ZyG6gVvBEtYypvbztRvFeCtBsTxE9tt+85tS6Y= -code.cloudfoundry.org/lager/v3 v3.0.2 h1:H0dcQY+814G1Ea0e5K/AMaMpcr+Pe5Iv+AALJEwrP9U= -code.cloudfoundry.org/lager/v3 v3.0.2/go.mod h1:zA6tOIWhr5uZUez+PGpdfBHDWQOfhOrr0cgKDagZPwk= +code.cloudfoundry.org/lager/v3 v3.0.3 h1:/UTmadZfIaKuT/whEinSxK1mzRfNu1uPfvjFfGqiwzM= +code.cloudfoundry.org/lager/v3 v3.0.3/go.mod h1:Zn5q1SrIuuHjEUE7xerMKt3ztunrJQCZETAo7rV0CH8= code.cloudfoundry.org/localip v0.0.0-20230406154046-f137f65d303d h1:UKggh2CVl4b5QtGFtZyVCiF6Y+sTtYIxFPw7crUZxGM= code.cloudfoundry.org/localip v0.0.0-20230406154046-f137f65d303d/go.mod h1:7CQS2p5BMdlH24kxSUdOUUXYTGHD6N3ikfnerNL77HI= code.cloudfoundry.org/locket v0.0.0-20230406154009-5e8522d975d2 h1:tUpafuylA0aTl6sdQnf20OsO/ipCvdNSZlWOB1cHhz8= @@ -170,8 +170,8 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= -github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A= -github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM= +github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= +github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/vendor/code.cloudfoundry.org/lager/v3/README.md b/vendor/code.cloudfoundry.org/lager/v3/README.md index 194b3386..9a4248ad 100644 --- a/vendor/code.cloudfoundry.org/lager/v3/README.md +++ b/vendor/code.cloudfoundry.org/lager/v3/README.md @@ -17,6 +17,30 @@ import ( logger := lager.NewLogger("my-app") ``` +### Lager and [`log/slog`](https://pkg.go.dev/log/slog) +Lager was written long before Go 1.21 introduced structured logging in the standard library. +There are some wrapper functions for interoperability between Lager and `slog`, +which are only available when using Go 1.21 and higher. + +Lager can be used as an [`slog.Handler`](https://pkg.go.dev/log/slog#Handler) using the `NewHandler()` function: + +```go +func codeThatAcceptsSlog(l *slog.Logger) { ... } + +lagerLogger := lager.NewLogger("my-lager-logger") + +codeThatAcceptsSlog(slog.New(lager.NewHandler(lagerLogger))) +``` + +An `slog.Logger` can be used as a Lager `Sink` using the `NewSlogSink()` function: +```go +var *slog.Logger l = codeThatReturnsSlog() + +lagerLogger := lager.NewLogger("my-lager-logger") + +lagerLogger.RegisterSink(lager.NewSlogSink(l)) +``` + ### Sinks Lager can write logs to a variety of destinations. You can specify the destinations diff --git a/vendor/code.cloudfoundry.org/lager/v3/handler.go b/vendor/code.cloudfoundry.org/lager/v3/handler.go new file mode 100644 index 00000000..2cdaf7c3 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/v3/handler.go @@ -0,0 +1,162 @@ +//go:build go1.21 + +package lager + +import ( + "context" + "fmt" + "log/slog" +) + +// NewHandler wraps the logger as a slog.Handler +// The supplied Logger must be a lager.logger +// type created by lager.NewLogger(), otherwise +// it panics. +// +// Note the following log level conversions: +// +// slog.LevelDebug -> lager.DEBUG +// slog.LevelError -> lager.ERROR +// slog.LevelError -> lager.FATAL +// default -> lager.INFO +func NewHandler(l Logger) slog.Handler { + switch ll := l.(type) { + case *logger: + return &handler{logger: ll} + default: + panic("lager.Logger must be an instance of lager.logger") + } +} + +// Type decorator is used to decorate the attributes with groups and more attributes +type decorator func(map[string]any) map[string]any + +// Type handler is a slog.Handler that wraps a lager logger. +// It uses the logger concrete type rather than the Logger interface +// because it uses methods not available on the interface. +type handler struct { + logger *logger + decorators []decorator +} + +// Enabled always returns true +func (h *handler) Enabled(_ context.Context, _ slog.Level) bool { + return true +} + +// Handle converts a slog.Record into a lager.LogFormat and passes it to every Sink +func (h *handler) Handle(_ context.Context, r slog.Record) error { + log := LogFormat{ + time: r.Time, + Timestamp: formatTimestamp(r.Time), + Source: h.logger.component, + Message: fmt.Sprintf("%s.%s", h.logger.task, r.Message), + LogLevel: toLogLevel(r.Level), + Data: h.logger.baseData(h.decorate(attrFromRecord(r))), + } + + for _, sink := range h.logger.sinks { + sink.Log(log) + } + + return nil +} + +// WithAttrs returns a new slog.Handler which always adds the specified attributes +func (h *handler) WithAttrs(attrs []slog.Attr) slog.Handler { + return &handler{ + logger: h.logger, + decorators: append(h.decorators, attrDecorator(attrs)), + } +} + +// WithGroup returns a new slog.Handler which always logs attributes in the specified group +func (h *handler) WithGroup(name string) slog.Handler { + return &handler{ + logger: h.logger, + decorators: append(h.decorators, groupDecorator(name)), + } +} + +// decorate will decorate a body using the decorators that have been defined +func (h *handler) decorate(body map[string]any) map[string]any { + for i := len(h.decorators) - 1; i >= 0; i-- { // reverse iteration + body = h.decorators[i](body) + } + return body +} + +// attrDecorator returns a decorator for the specified attributes +func attrDecorator(attrs []slog.Attr) decorator { + return func(body map[string]any) map[string]any { + if body == nil { + body = make(map[string]any) + } + processAttrs(attrs, body) + return body + } +} + +// groupDecorator returns a decorator for the specified group name +func groupDecorator(group string) decorator { + return func(body map[string]any) map[string]any { + switch len(body) { + case 0: + return nil + default: + return map[string]any{group: body} + } + } +} + +// attrFromRecord extracts and processes the attributes from a record +func attrFromRecord(r slog.Record) map[string]any { + if r.NumAttrs() == 0 { + return nil + } + + body := make(map[string]any, r.NumAttrs()) + r.Attrs(func(attr slog.Attr) bool { + processAttr(attr, body) + return true + }) + + return body +} + +// processAttrs calls processAttr() for each attribute +func processAttrs(attrs []slog.Attr, target map[string]any) { + for _, attr := range attrs { + processAttr(attr, target) + } +} + +// processAttr adds the attribute to the target with appropriate transformations +func processAttr(attr slog.Attr, target map[string]any) { + rv := attr.Value.Resolve() + + switch { + case rv.Kind() == slog.KindGroup && attr.Key != "": + nt := make(map[string]any) + processAttrs(attr.Value.Group(), nt) + target[attr.Key] = nt + case rv.Kind() == slog.KindGroup && attr.Key == "": + processAttrs(attr.Value.Group(), target) + case attr.Key == "": + // skip + default: + target[attr.Key] = rv.Any() + } +} + +// toLogLevel converts from slog levels to lager levels +func toLogLevel(l slog.Level) LogLevel { + switch l { + case slog.LevelDebug: + return DEBUG + case slog.LevelError, slog.LevelWarn: + return ERROR + default: + return INFO + } +} diff --git a/vendor/code.cloudfoundry.org/lager/v3/slog_sink.go b/vendor/code.cloudfoundry.org/lager/v3/slog_sink.go new file mode 100644 index 00000000..095e16a6 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/v3/slog_sink.go @@ -0,0 +1,63 @@ +//go:build go1.21 + +package lager + +import ( + "context" + "log/slog" +) + +// Type slogSink wraps an slog.Logger as a Sink +type slogSink struct { + logger *slog.Logger +} + +// NewSlogSink wraps a slog.Logger as a lager Sink +// This allows code using slog to integrate with code that uses lager +// Note the following log level conversions: +// +// lager.DEBUG -> slog.LevelDebug +// lager.ERROR -> slog.LevelError +// lager.FATAL -> slog.LevelError +// default -> slog.LevelInfo +func NewSlogSink(l *slog.Logger) Sink { + return &slogSink{logger: l} +} + +// Log exists to implement the lager.Sink interface. +func (l *slogSink) Log(f LogFormat) { + // For lager.Error() and lager.Fatal() the error (and stacktrace) are already in f.Data + r := slog.NewRecord(f.time, toSlogLevel(f.LogLevel), f.Message, 0) + r.AddAttrs(toAttr(f.Data)...) + + // By calling the handler directly we can pass through the original timestamp, + // whereas calling a method on the logger would generate a new timestamp + l.logger.Handler().Handle(context.Background(), r) +} + +// toAttr converts a lager.Data into []slog.Attr +func toAttr(d Data) []slog.Attr { + l := len(d) + if l == 0 { + return nil + } + + attr := make([]slog.Attr, 0, l) + for k, v := range d { + attr = append(attr, slog.Any(k, v)) + } + + return attr +} + +// toSlogLevel converts lager log levels to slog levels +func toSlogLevel(l LogLevel) slog.Level { + switch l { + case DEBUG: + return slog.LevelDebug + case ERROR, FATAL: + return slog.LevelError + default: + return slog.LevelInfo + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 1038e671..69af409a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -31,7 +31,7 @@ code.cloudfoundry.org/go-diodes code.cloudfoundry.org/go-loggregator/v8 code.cloudfoundry.org/go-loggregator/v8/rfc5424 code.cloudfoundry.org/go-loggregator/v8/rpc/loggregator_v2 -# code.cloudfoundry.org/lager/v3 v3.0.2 +# code.cloudfoundry.org/lager/v3 v3.0.3 ## explicit; go 1.19 code.cloudfoundry.org/lager/v3 code.cloudfoundry.org/lager/v3/internal/truncate @@ -168,7 +168,7 @@ github.com/onsi/gomega/matchers/support/goraph/edge github.com/onsi/gomega/matchers/support/goraph/node github.com/onsi/gomega/matchers/support/goraph/util github.com/onsi/gomega/types -# github.com/openzipkin/zipkin-go v0.4.1 +# github.com/openzipkin/zipkin-go v0.4.2 ## explicit; go 1.18 github.com/openzipkin/zipkin-go/idgenerator github.com/openzipkin/zipkin-go/model