From b82d79a59f042560cfcc100a17001390f602bdfa Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Tue, 19 Mar 2024 11:04:33 -0700 Subject: [PATCH] Add skeleton of slog bridge (#5292) * Add slog bridge skeleton * Apply feedback Add LoggerProvider as an option. Rename New to NewHandler. Add the New function to return an *slog.Logger. * Rename New to NewLogger --- .github/dependabot.yml | 9 +++ bridges/otelslog/go.mod | 16 ++++++ bridges/otelslog/go.sum | 25 ++++++++ bridges/otelslog/handler.go | 112 ++++++++++++++++++++++++++++++++++++ versions.yaml | 1 + 5 files changed, 163 insertions(+) create mode 100644 bridges/otelslog/go.mod create mode 100644 bridges/otelslog/go.sum create mode 100644 bridges/otelslog/handler.go diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ade8c371d10..bb6bf7d7278 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -100,6 +100,15 @@ updates: schedule: interval: weekly day: sunday + - package-ecosystem: gomod + directory: /bridges/otelslog + labels: + - dependencies + - go + - Skip Changelog + schedule: + interval: weekly + day: sunday - package-ecosystem: gomod directory: /bridges/prometheus labels: diff --git a/bridges/otelslog/go.mod b/bridges/otelslog/go.mod new file mode 100644 index 00000000000..602a1f4f7e6 --- /dev/null +++ b/bridges/otelslog/go.mod @@ -0,0 +1,16 @@ +module go.opentelemetry.io/contrib/bridges/otelslog + +go 1.21 + +require ( + go.opentelemetry.io/otel/log v0.0.1-alpha + go.opentelemetry.io/otel/sdk v1.24.0 +) + +require ( + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect +) diff --git a/bridges/otelslog/go.sum b/bridges/otelslog/go.sum new file mode 100644 index 00000000000..71b4042c141 --- /dev/null +++ b/bridges/otelslog/go.sum @@ -0,0 +1,25 @@ +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.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/log v0.0.1-alpha h1:Gy4SxFnkHv2wmmzv//sblb4/PoCYVtuZbdFY/XamvHM= +go.opentelemetry.io/otel/log v0.0.1-alpha/go.mod h1:fg1zxLfxAyzlCLyULJTWXUbFVYyOwQZD/DgtGm7VvgA= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/bridges/otelslog/handler.go b/bridges/otelslog/handler.go new file mode 100644 index 00000000000..7d95bc91f24 --- /dev/null +++ b/bridges/otelslog/handler.go @@ -0,0 +1,112 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package otelslog provides [Handler], an [slog.Handler] implementation, that +// can be used to bridge between the [log/slog] API and [OpenTelemetry]. +// +// [OpenTelemetry]: https://opentelemetry.io/docs/concepts/signals/logs/ +package otelslog // import "go.opentelemetry.io/contrib/bridges/otelslog" + +import ( + "context" + "log/slog" + + "go.opentelemetry.io/otel/log" + "go.opentelemetry.io/otel/sdk/instrumentation" +) + +// NewLogger returns a new [slog.Logger] backed by a new [Handler]. See +// [NewHandler] for details on how the backing Handler is created. +func NewLogger(options ...Option) *slog.Logger { + return slog.New(NewHandler(options...)) +} + +type config struct{} + +// Option configures a [Handler]. +type Option interface { + apply(config) config +} + +type optFunc func(config) config + +func (f optFunc) apply(c config) config { return f(c) } + +// WithInstrumentationScope returns an [Option] that configures the scope of +// the [log.Logger] used by a [Handler]. +// +// By default if this Option is not provided, the Handler will use a default +// instrumentation scope describing this bridge package. It is recommended to +// provide this so log data can be associated with its source package or +// module. +func WithInstrumentationScope(scope instrumentation.Scope) Option { + return optFunc(func(c config) config { + // TODO: implement. + return c + }) +} + +// WithLoggerProvider returns an [Option] that configures [log.LoggerProvider] +// used by a [Handler] to create its [log.Logger]. +// +// By default if this Option is not provided, the Handler will use the global +// LoggerProvider. +func WithLoggerProvider(provider log.LoggerProvider) Option { + return optFunc(func(c config) config { + // TODO: implement. + return c + }) +} + +// Handler is an [slog.Handler] that sends all logging records it receives to +// OpenTelemetry. +type Handler struct { + // Ensure forward compatibility by explicitly making this not comparable. + noCmp [0]func() //nolint: unused // This is indeed used. + + // TODO: implement. +} + +// Compile-time check *Handler implements slog.Handler. +var _ slog.Handler = (*Handler)(nil) + +// NewHandler returns a new [Handler] to be used as an [slog.Handler]. +// +// If [WithLoggerProvider] is not provided, the returned Handler will use the +// global LoggerProvider. +// +// By default the returned Handler will use a [log.Logger] that is identified +// with this bridge package information. [WithInstrumentationScope] should be +// used to override this with details about the package or module the handler +// will instrument. +func NewHandler(options ...Option) *Handler { + // TODO: implement. + return &Handler{} +} + +// Handle handles the passed record. +func (h *Handler) Handle(ctx context.Context, record slog.Record) error { + // TODO: implement. + return nil +} + +// Enable returns true if the Handler is enabled to log for the provided +// context and Level. Otherwise, false is returned if it is not enabled. +func (h *Handler) Enabled(context.Context, slog.Level) bool { + // TODO: implement. + return true +} + +// WithAttrs returns a new [slog.Handler] based on h that will log using the +// passed attrs. +func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler { + // TODO: implement. + return h +} + +// WithGroup returns a new [slog.Handler] based on h that will log all messages +// and attributes within a group of the provided name. +func (h *Handler) WithGroup(name string) slog.Handler { + // TODO: implement. + return h +} diff --git a/versions.yaml b/versions.yaml index bc965e94319..e6785a8710a 100644 --- a/versions.yaml +++ b/versions.yaml @@ -75,6 +75,7 @@ module-sets: modules: - go.opentelemetry.io/contrib/config excluded-modules: + - go.opentelemetry.io/contrib/bridges/slog - go.opentelemetry.io/contrib/instrgen - go.opentelemetry.io/contrib/instrgen/driver - go.opentelemetry.io/contrib/instrgen/testdata/interface