Skip to content

Commit

Permalink
Implement the slog bridge config (#5311)
Browse files Browse the repository at this point in the history
* Add Version func

* Implement the config

* Add TestNewHandlerConfiguration

* Replace Version func with const
  • Loading branch information
MrAlias authored Mar 20, 2024
1 parent 7169a6f commit 851b2fd
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 6 deletions.
48 changes: 43 additions & 5 deletions bridges/otelslog/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,54 @@ import (
"log/slog"

"go.opentelemetry.io/otel/log"
"go.opentelemetry.io/otel/log/global"
"go.opentelemetry.io/otel/sdk/instrumentation"
)

const bridgeName = "go.opentelemetry.io/contrib/bridges/otelslog"

// 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{}
type config struct {
provider log.LoggerProvider
scope instrumentation.Scope
}

func newConfig(options []Option) config {
var c config
for _, opt := range options {
c = opt.apply(c)
}

var emptyScope instrumentation.Scope
if c.scope == emptyScope {
c.scope = instrumentation.Scope{
Name: bridgeName,
Version: version,
}
}

if c.provider == nil {
c.provider = global.GetLoggerProvider()
}

return c
}

func (c config) logger() log.Logger {
var opts []log.LoggerOption
if c.scope.Version != "" {
opts = append(opts, log.WithInstrumentationVersion(c.scope.Version))
}
if c.scope.SchemaURL != "" {
opts = append(opts, log.WithSchemaURL(c.scope.SchemaURL))
}
return c.provider.Logger(c.scope.Name, opts...)
}

// Option configures a [Handler].
type Option interface {
Expand All @@ -41,7 +79,7 @@ func (f optFunc) apply(c config) config { return f(c) }
// module.
func WithInstrumentationScope(scope instrumentation.Scope) Option {
return optFunc(func(c config) config {
// TODO: implement.
c.scope = scope
return c
})
}
Expand All @@ -53,7 +91,7 @@ func WithInstrumentationScope(scope instrumentation.Scope) Option {
// LoggerProvider.
func WithLoggerProvider(provider log.LoggerProvider) Option {
return optFunc(func(c config) config {
// TODO: implement.
c.provider = provider
return c
})
}
Expand All @@ -80,8 +118,8 @@ var _ slog.Handler = (*Handler)(nil)
// used to override this with details about the package or module the handler
// will instrument.
func NewHandler(options ...Option) *Handler {
// TODO: implement.
return &Handler{}
cfg := newConfig(options)
return &Handler{logger: cfg.logger()}
}

// Handle handles the passed record.
Expand Down
52 changes: 51 additions & 1 deletion bridges/otelslog/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"go.opentelemetry.io/otel/log"
"go.opentelemetry.io/otel/log/embedded"
"go.opentelemetry.io/otel/log/global"
"go.opentelemetry.io/otel/sdk/instrumentation"
)

func TestNewLogger(t *testing.T) {
Expand All @@ -27,14 +30,28 @@ type recorder struct {
embedded.LoggerProvider
embeddedLogger // nolint:unused // Used to embed embedded.Logger.

// Scope is the Logger scope recorder received when Logger was called.
Scope instrumentation.Scope

// MinSeverity is the minimum severity the recorder will return true for
// when Enabled is called (unless enableKey is set).
MinSeverity log.Severity
}

func (r *recorder) Logger(string, ...log.LoggerOption) log.Logger { return r }
func (r *recorder) Logger(name string, opts ...log.LoggerOption) log.Logger {
cfg := log.NewLoggerConfig(opts...)

r2 := *r
r2.Scope = instrumentation.Scope{
Name: name,
Version: cfg.InstrumentationVersion(),
SchemaURL: cfg.SchemaURL(),
}
return &r2
}

func (r *recorder) Emit(context.Context, log.Record) {
// TODO: implement.
}

type enablerKey uint
Expand All @@ -45,6 +62,39 @@ func (r *recorder) Enabled(ctx context.Context, record log.Record) bool {
return ctx.Value(enableKey) != nil || record.Severity() >= r.MinSeverity
}

func TestNewHandlerConfiguration(t *testing.T) {
t.Run("Default", func(t *testing.T) {
r := new(recorder)
global.SetLoggerProvider(r)

var h *Handler
assert.NotPanics(t, func() { h = NewHandler() })
assert.NotNil(t, h.logger)
require.IsType(t, &recorder{}, h.logger)

l := h.logger.(*recorder)
want := instrumentation.Scope{Name: bridgeName, Version: version}
assert.Equal(t, want, l.Scope)
})

t.Run("Options", func(t *testing.T) {
r := new(recorder)
scope := instrumentation.Scope{Name: "name", Version: "ver", SchemaURL: "url"}
var h *Handler
assert.NotPanics(t, func() {
h = NewHandler(
WithLoggerProvider(r),
WithInstrumentationScope(scope),
)
})
assert.NotNil(t, h.logger)
require.IsType(t, &recorder{}, h.logger)

l := h.logger.(*recorder)
assert.Equal(t, scope, l.Scope)
})
}

func TestHandlerEnabled(t *testing.T) {
r := new(recorder)
r.MinSeverity = log.SeverityInfo
Expand Down
7 changes: 7 additions & 0 deletions bridges/otelslog/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package otelslog // import "go.opentelemetry.io/contrib/bridges/otelslog"

// version is the current release version of otelslog in use.
const version = "0.0.1-alpha"

0 comments on commit 851b2fd

Please sign in to comment.