diff --git a/log/internal/global/log.go b/log/internal/global/log.go index acd333e8b19..c7d5d73de72 100644 --- a/log/internal/global/log.go +++ b/log/internal/global/log.go @@ -87,12 +87,11 @@ func (l *logger) Emit(ctx context.Context, r log.Record) { } } -func (l *logger) Enabled(ctx context.Context, r log.Record) bool { - var enabled bool +func (l *logger) IsEnabled(ctx context.Context, opts ...log.LoggerEnabledOption) bool { if del, ok := l.delegate.Load().(log.Logger); ok { - enabled = del.Enabled(ctx, r) + return del.IsEnabled(ctx, opts...) } - return enabled + return false } func (l *logger) setDelegate(provider log.LoggerProvider) { diff --git a/log/internal/global/log_test.go b/log/internal/global/log_test.go index f465abc9011..2ee73b891f6 100644 --- a/log/internal/global/log_test.go +++ b/log/internal/global/log_test.go @@ -55,7 +55,7 @@ func TestLoggerConcurrentSafe(t *testing.T) { var enabled bool for { l.Emit(ctx, r) - enabled = l.Enabled(ctx, r) + enabled = l.IsEnabled(ctx) select { case <-stop: @@ -103,16 +103,16 @@ type testLogger struct { } func (l *testLogger) Emit(context.Context, log.Record) { l.emitN++ } -func (l *testLogger) Enabled(context.Context, log.Record) bool { +func (l *testLogger) IsEnabled(context.Context, ...log.LoggerEnabledOption) bool { l.enabledN++ return true } -func emitRecord(l log.Logger) { +func emitRecord(t testing.TB, l log.Logger) { ctx := context.Background() var r log.Record - _ = l.Enabled(ctx, r) + assert.True(t, l.IsEnabled(ctx)) l.Emit(ctx, r) } @@ -143,15 +143,15 @@ func TestDelegation(t *testing.T) { want++ assert.Equal(t, want, delegate.loggerN, "new Logger not delegated") - emitRecord(pre0) - emitRecord(pre2) + emitRecord(t, pre0) + emitRecord(t, pre2) if assert.IsType(t, &testLogger{}, pre2, "wrong pre-delegation Logger type") { assert.Equal(t, 2, pre2.(*testLogger).emitN, "Emit not delegated") assert.Equal(t, 2, pre2.(*testLogger).enabledN, "Enabled not delegated") } - emitRecord(post) + emitRecord(t, post) if assert.IsType(t, &testLogger{}, post, "wrong post-delegation Logger type") { assert.Equal(t, 1, post.(*testLogger).emitN, "Emit not delegated") diff --git a/log/logger.go b/log/logger.go index df2e88ea6b2..133364419dd 100644 --- a/log/logger.go +++ b/log/logger.go @@ -30,7 +30,7 @@ type Logger interface { // concurrently. Emit(ctx context.Context, record Record) - // Enabled returns whether the Logger emits for the given context and + // IsEnabled returns whether the Logger emits for the given context and // record. // // The passed record is likely to be a partial record with only the @@ -50,7 +50,7 @@ type Logger interface { // // Implementations of this method need to be safe for a user to call // concurrently. - Enabled(ctx context.Context, record Record) bool + IsEnabled(ctx context.Context, opts ...LoggerEnabledOption) bool } // LoggerOption applies configuration options to a [Logger]. @@ -129,3 +129,9 @@ func WithSchemaURL(schemaURL string) LoggerOption { return config }) } + +// LoggerEnabledOption applies configuration options to a [Logger.IsEnabled]. +type LoggerEnabledOption interface { + // Define EnabledConfig when needed. + applyLogger() +} diff --git a/log/logtest/recorder.go b/log/logtest/recorder.go index b3d45d647ae..eb5e128231a 100644 --- a/log/logtest/recorder.go +++ b/log/logtest/recorder.go @@ -11,9 +11,9 @@ import ( "go.opentelemetry.io/otel/log/embedded" ) -type enabledFn func(context.Context, log.Record) bool +type enabledFn func(context.Context, []log.LoggerEnabledOption) bool -var defaultEnabledFunc = func(context.Context, log.Record) bool { +var defaultEnabledFunc = func(context.Context, []log.LoggerEnabledOption) bool { return true } @@ -42,7 +42,7 @@ func (f optFunc) apply(c config) config { return f(c) } // WithEnabledFunc allows configuring whether the [Recorder] is enabled for specific log entries or not. // // By default, the Recorder is enabled for every log entry. -func WithEnabledFunc(fn func(context.Context, log.Record) bool) Option { +func WithEnabledFunc(fn func(context.Context, []log.LoggerEnabledOption) bool) Option { return optFunc(func(c config) config { c.enabledFn = fn return c @@ -155,12 +155,12 @@ type logger struct { } // Enabled indicates whether a specific record should be stored. -func (l *logger) Enabled(ctx context.Context, record log.Record) bool { +func (l *logger) IsEnabled(ctx context.Context, opts ...log.LoggerEnabledOption) bool { if l.enabledFn == nil { - return defaultEnabledFunc(ctx, record) + return defaultEnabledFunc(ctx, opts) } - return l.enabledFn(ctx, record) + return l.enabledFn(ctx, opts) } // Emit stores the log record. diff --git a/log/logtest/recorder_test.go b/log/logtest/recorder_test.go index 15f67d0e6de..92d4ae822fe 100644 --- a/log/logtest/recorder_test.go +++ b/log/logtest/recorder_test.go @@ -65,39 +65,32 @@ func TestRecorderLoggerCreatesNewStruct(t *testing.T) { func TestLoggerEnabled(t *testing.T) { for _, tt := range []struct { - name string - options []Option - ctx context.Context - buildRecord func() log.Record + name string + options []Option + ctx context.Context isEnabled bool }{ { name: "the default option enables every log entry", ctx: context.Background(), - buildRecord: func() log.Record { - return log.Record{} - }, isEnabled: true, }, { name: "with everything disabled", options: []Option{ - WithEnabledFunc(func(context.Context, log.Record) bool { + WithEnabledFunc(func(context.Context, []log.LoggerEnabledOption) bool { return false }), }, ctx: context.Background(), - buildRecord: func() log.Record { - return log.Record{} - }, isEnabled: false, }, } { t.Run(tt.name, func(t *testing.T) { - e := NewRecorder(tt.options...).Logger("test").Enabled(tt.ctx, tt.buildRecord()) + e := NewRecorder(tt.options...).Logger("test").IsEnabled(tt.ctx) assert.Equal(t, tt.isEnabled, e) }) } @@ -105,7 +98,7 @@ func TestLoggerEnabled(t *testing.T) { func TestLoggerEnabledFnUnset(t *testing.T) { r := &logger{} - assert.True(t, r.Enabled(context.Background(), log.Record{})) + assert.True(t, r.IsEnabled(context.Background())) } func TestRecorderEmitAndReset(t *testing.T) { @@ -158,7 +151,7 @@ func TestRecorderConcurrentSafe(t *testing.T) { defer wg.Done() nr := r.Logger("test") - nr.Enabled(context.Background(), log.Record{}) + nr.IsEnabled(context.Background()) nr.Emit(context.Background(), log.Record{}) r.Result() diff --git a/log/noop/noop.go b/log/noop/noop.go index d2e21edba66..654c6cd66f5 100644 --- a/log/noop/noop.go +++ b/log/noop/noop.go @@ -47,4 +47,4 @@ type Logger struct{ embedded.Logger } func (Logger) Emit(context.Context, log.Record) {} // Enabled returns false. No log records are ever emitted. -func (Logger) Enabled(context.Context, log.Record) bool { return false } +func (Logger) IsEnabled(context.Context, ...log.LoggerEnabledOption) bool { return false } diff --git a/sdk/log/logger.go b/sdk/log/logger.go index db41c057005..7ef3b8ec947 100644 --- a/sdk/log/logger.go +++ b/sdk/log/logger.go @@ -43,20 +43,10 @@ func (l *logger) Emit(ctx context.Context, r log.Record) { } } -// Enabled returns true if at least one Processor held by the LoggerProvider +// IsEnabled returns true if at least one Processor held by the LoggerProvider // that created the logger will process the record for the provided context. -// -// If it is not possible to definitively determine the record will be -// processed, true will be returned by default. A value of false will only be -// returned if it can be positively verified that no Processor will process the -// record. -func (l *logger) Enabled(ctx context.Context, record log.Record) bool { - fltrs := l.provider.filterProcessors() - // If there are more Processors than FilterProcessors we cannot be sure - // that all Processors will drop the record. Therefore, return true. - // - // If all Processors are FilterProcessors, check if any is enabled. - return len(l.provider.processors) > len(fltrs) || anyEnabled(ctx, record, fltrs) +func (l *logger) IsEnabled(context.Context, ...log.LoggerEnabledOption) bool { + return len(l.provider.processors) > 0 } func anyEnabled(ctx context.Context, r log.Record, fltrs []x.FilterProcessor) bool { diff --git a/sdk/log/logger_test.go b/sdk/log/logger_test.go index bfa967232ec..5b9d74295cf 100644 --- a/sdk/log/logger_test.go +++ b/sdk/log/logger_test.go @@ -215,9 +215,7 @@ func TestLoggerEmit(t *testing.T) { } func TestLoggerEnabled(t *testing.T) { - p0 := newFltrProcessor("0", true) - p1 := newFltrProcessor("1", true) - p2WithDisabled := newFltrProcessor("2", false) + p0 := newProcessor("0") testCases := []struct { name string @@ -235,24 +233,6 @@ func TestLoggerEnabled(t *testing.T) { name: "WithProcessors", logger: newLogger(NewLoggerProvider( WithProcessor(p0), - WithProcessor(p1), - ), instrumentation.Scope{}), - ctx: context.Background(), - expected: true, - }, - { - name: "WithDisabledProcessors", - logger: newLogger(NewLoggerProvider( - WithProcessor(p2WithDisabled), - ), instrumentation.Scope{}), - ctx: context.Background(), - expected: false, - }, - { - name: "ContainsDisabledProcessor", - logger: newLogger(NewLoggerProvider( - WithProcessor(p2WithDisabled), - WithProcessor(p0), ), instrumentation.Scope{}), ctx: context.Background(), expected: true, @@ -261,7 +241,6 @@ func TestLoggerEnabled(t *testing.T) { name: "WithNilContext", logger: newLogger(NewLoggerProvider( WithProcessor(p0), - WithProcessor(p1), ), instrumentation.Scope{}), ctx: nil, expected: true, @@ -270,19 +249,17 @@ func TestLoggerEnabled(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.expected, tc.logger.Enabled(tc.ctx, log.Record{})) + assert.Equal(t, tc.expected, tc.logger.IsEnabled(tc.ctx)) }) } } func BenchmarkLoggerEnabled(b *testing.B) { provider := NewLoggerProvider( - WithProcessor(newFltrProcessor("0", false)), - WithProcessor(newFltrProcessor("1", true)), + WithProcessor(newProcessor("0")), ) logger := provider.Logger("BenchmarkLoggerEnabled") - ctx, r := context.Background(), log.Record{} - r.SetSeverityText("test") + ctx := context.Background() var enabled bool @@ -290,7 +267,7 @@ func BenchmarkLoggerEnabled(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - enabled = logger.Enabled(ctx, r) + enabled = logger.IsEnabled(ctx) } _ = enabled diff --git a/sdk/log/provider_test.go b/sdk/log/provider_test.go index 4dd9cf327e9..789835cc082 100644 --- a/sdk/log/provider_test.go +++ b/sdk/log/provider_test.go @@ -20,7 +20,6 @@ import ( "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/log" "go.opentelemetry.io/otel/log/noop" - "go.opentelemetry.io/otel/sdk/log/internal/x" "go.opentelemetry.io/otel/sdk/resource" ) @@ -57,25 +56,6 @@ func (p *processor) ForceFlush(context.Context) error { return p.Err } -type fltrProcessor struct { - *processor - - enabled bool -} - -var _ x.FilterProcessor = (*fltrProcessor)(nil) - -func newFltrProcessor(name string, enabled bool) *fltrProcessor { - return &fltrProcessor{ - processor: newProcessor(name), - enabled: enabled, - } -} - -func (p *fltrProcessor) Enabled(context.Context, log.Record) bool { - return p.enabled -} - func TestNewLoggerProviderConfiguration(t *testing.T) { t.Cleanup(func(orig otel.ErrorHandler) func() { otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { @@ -321,5 +301,5 @@ func BenchmarkLoggerProviderLogger(b *testing.B) { } b.StopTimer() - loggers[0].Enabled(context.Background(), log.Record{}) + loggers[0].IsEnabled(context.Background()) }