Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
flc1125 committed Dec 23, 2024
1 parent 00786cc commit 7860af2
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 24 deletions.
40 changes: 33 additions & 7 deletions bridges/otellogr/logsink.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ import (
)

type config struct {
provider log.LoggerProvider
version string
schemaURL string

provider log.LoggerProvider
version string
schemaURL string
ctx context.Context
levelSeverity func(int) log.Severity
}

Expand All @@ -82,6 +82,10 @@ func newConfig(options []Option) config {
c.provider = global.GetLoggerProvider()
}

if c.ctx == nil {
c.ctx = context.Background()
}

if c.levelSeverity == nil {
c.levelSeverity = func(level int) log.Severity {
switch level {
Expand Down Expand Up @@ -139,6 +143,18 @@ func WithLoggerProvider(provider log.LoggerProvider) Option {
})
}

// WithContext returns an [Option] that configures the [context.Context] used by
// a [LogSink].
//
// By default if this Option is not provided, the LogSink will use the
// background context.
func WithContext(ctx context.Context) Option {
return optFunc(func(c config) config {
c.ctx = ctx
return c
})
}

// WithLevelSeverity returns an [Option] that configures the function used to
// convert logr levels to OpenTelemetry log severities.
//
Expand Down Expand Up @@ -176,6 +192,7 @@ func NewLogSink(name string, options ...Option) *LogSink {
logger: c.provider.Logger(name, opts...),
levelSeverity: c.levelSeverity,
opts: opts,
ctx: c.ctx,
}
}

Expand All @@ -201,9 +218,8 @@ var _ logr.LogSink = (*LogSink)(nil)
// For example, commandline flags might be used to set the logging
// verbosity and disable some info logs.
func (l *LogSink) Enabled(level int) bool {
ctx := context.Background()
param := log.EnabledParameters{Severity: l.levelSeverity(level)}
return l.logger.Enabled(ctx, param)
return l.logger.Enabled(l.ctx, param)
}

// Error logs an error, with the given message and key/value pairs.
Expand Down Expand Up @@ -238,9 +254,19 @@ func (l *LogSink) Info(level int, msg string, keysAndValues ...any) {
l.logger.Emit(ctx, record)
}

func (l *LogSink) WithContext(ctx context.Context) *LogSink {
if ctx == nil {
return l
}
sink := new(LogSink)
*sink = *l
sink.ctx = ctx
return sink
}

// Init receives optional information about the logr library this
// implementation does not use it.
func (l *LogSink) Init(info logr.RuntimeInfo) {
func (l *LogSink) Init(logr.RuntimeInfo) {
// We don't need to do anything here.
// CallDepth is used to calculate the caller's PC.
// PC is dropped as part of the conversion to the OpenTelemetry log.Record.
Expand Down
72 changes: 55 additions & 17 deletions bridges/otellogr/logsink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,53 @@ func TestNewConfig(t *testing.T) {
customLoggerProvider := mockLoggerProvider{}

for _, tt := range []struct {
name string
options []Option

wantConfig config
name string
options []Option
wantFunc func(config)
}{
{
name: "with no options",

wantConfig: config{
provider: global.GetLoggerProvider(),
wantFunc: func(c config) {
assert.Equal(t, global.GetLoggerProvider(), c.provider)
},
},
{
name: "with a custom instrumentation scope",
options: []Option{
WithVersion("42.0"),
},

wantConfig: config{
version: "42.0",
provider: global.GetLoggerProvider(),
wantFunc: func(c config) {
assert.Equal(t, "42.0", c.version)
},
},
{
name: "with a custom logger provider",
options: []Option{
WithLoggerProvider(customLoggerProvider),
},

wantConfig: config{
provider: customLoggerProvider,
wantFunc: func(c config) {
assert.Equal(t, customLoggerProvider, c.provider)
},
},
{
name: "default context",
options: []Option{},
wantFunc: func(c config) {
assert.Equal(t, context.Background(), c.ctx)
},
},
{
name: "with a custom context",
options: []Option{
WithContext(context.WithValue(context.Background(), "key", "value")),
},
wantFunc: func(c config) {
assert.Equal(t, context.WithValue(context.Background(), "key", "value"), c.ctx)
},
},
} {
t.Run(tt.name, func(t *testing.T) {
config := newConfig(tt.options)
config.levelSeverity = nil // Ignore asserting level severity function, assert.Equal does not support function comparison
assert.Equal(t, tt.wantConfig, config)
tt.wantFunc(newConfig(tt.options))
})
}
}
Expand Down Expand Up @@ -375,6 +384,35 @@ func TestLogSinkEnabled(t *testing.T) {
assert.False(t, ls.Enabled(1))
}

func TestLogSinkWithContext(t *testing.T) {
rec := logtest.NewRecorder()
ls := NewLogSink(
"name",
WithLoggerProvider(rec),
)

t.Run("no context", func(t *testing.T) {
defer rec.Reset()
ls.Info(0, "msg")
require.Len(t, rec.Result(), 1)
require.Len(t, rec.Result()[0].Records, 1)
assert.Empty(t, rec.Result()[0].Records[0].Context())
})

t.Run("with context", func(t *testing.T) {
defer rec.Reset()

ctx := context.WithValue(context.Background(), "key", "value")
ls2 := ls.WithContext(ctx)
assert.NotSame(t, ls, ls2)

ls2.Info(0, "msg")
require.Len(t, rec.Result(), 1)
require.Len(t, rec.Result()[0].Records, 1)
assert.Equal(t, "value", rec.Result()[0].Records[0].Context().Value("key"))
})
}

func buildRecord(body log.Value, timestamp time.Time, severity log.Severity, attrs []log.KeyValue) log.Record {
var record log.Record
record.SetBody(body)
Expand Down

0 comments on commit 7860af2

Please sign in to comment.