1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2026-06-03 18:35:08 +02:00

log: Introduce EnabledParameters (#5791)

Fixes https://github.com/open-telemetry/opentelemetry-go/issues/5769

Related spec PR:
https://github.com/open-telemetry/opentelemetry-specification/pull/4203

Remark: A follow-up in contrib is required and afterwards here to fix
the `example/dice`.

Benchstat results for `sdk/log` (`log` has no benchmarks related to
Enabled):

```
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/log
cpu: Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz
                                  │    old.txt    │               new.txt                │
                                  │    sec/op     │    sec/op     vs base                │
BatchProcessorOnEmit-16              398.8n ± 10%   395.6n ± 12%        ~ (p=0.971 n=10)
Processor/Simple-16                  882.2n ±  8%   869.8n ±  9%        ~ (p=0.811 n=10)
Processor/Batch-16                   1.478µ ±  3%   1.485µ ±  5%        ~ (p=0.646 n=10)
Processor/SetTimestampSimple-16      847.8n ±  1%   844.6n ±  3%        ~ (p=0.247 n=10)
Processor/SetTimestampBatch-16       1.480µ ±  3%   1.473µ ±  4%        ~ (p=0.700 n=10)
Processor/AddAttributesSimple-16     930.0n ±  1%   933.8n ±  1%        ~ (p=0.172 n=10)
Processor/AddAttributesBatch-16      1.624µ ±  2%   1.639µ ±  2%        ~ (p=0.839 n=10)
Processor/SetAttributesSimple-16     903.4n ±  1%   895.1n ±  1%        ~ (p=0.190 n=10)
Processor/SetAttributesBatch-16      1.554µ ±  4%   1.529µ ±  3%        ~ (p=0.159 n=10)
LoggerNewRecord/5_attributes-16      346.0n ±  2%   343.3n ±  2%        ~ (p=0.448 n=10)
LoggerNewRecord/10_attributes-16     1.608µ ±  6%   1.503µ ±  2%   -6.53% (p=0.007 n=10)
LoggerEnabled-16                    34.305n ±  8%   6.706n ±  1%  -80.45% (p=0.000 n=10)
LoggerProviderLogger-16              636.9n ± 10%   605.8n ±  3%        ~ (p=0.105 n=10)
WalkAttributes/1_attributes-16       5.363n ±  3%   4.540n ± 14%  -15.34% (p=0.002 n=10)
WalkAttributes/10_attributes-16      5.436n ±  7%   4.461n ±  2%  -17.95% (p=0.000 n=10)
WalkAttributes/100_attributes-16     5.126n ±  9%   4.465n ±  1%  -12.90% (p=0.000 n=10)
WalkAttributes/1000_attributes-16    5.316n ±  9%   4.502n ±  5%  -15.32% (p=0.002 n=10)
SetAddAttributes/SetAttributes-16    220.5n ± 18%   192.6n ± 11%  -12.67% (p=0.007 n=10)
SetAddAttributes/AddAttributes-16    165.3n ± 21%   127.3n ± 22%  -22.96% (p=0.011 n=10)
SimpleProcessorOnEmit-16             2.159n ±  9%   2.167n ±  9%        ~ (p=0.739 n=10)
geomean                              178.3n         154.5n        -13.31%

                        │    old.txt    │             new.txt             │
                        │      B/s      │      B/s       vs base          │
BatchProcessorOnEmit-16   76.52Mi ± 11%   77.14Mi ± 14%  ~ (p=0.971 n=10)

                                  │    old.txt     │                new.txt                │
                                  │      B/op      │     B/op      vs base                 │
BatchProcessorOnEmit-16               0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/Simple-16                   417.0 ± 0%       417.0 ± 0%       ~ (p=1.000 n=10) ¹
Processor/Batch-16                  1.093Ki ± 1%     1.088Ki ± 1%       ~ (p=0.254 n=10)
Processor/SetTimestampSimple-16       417.0 ± 0%       417.0 ± 0%       ~ (p=1.000 n=10) ¹
Processor/SetTimestampBatch-16      1.095Ki ± 1%     1.084Ki ± 2%       ~ (p=0.361 n=10)
Processor/AddAttributesSimple-16      417.0 ± 0%       417.0 ± 0%       ~ (p=1.000 n=10) ¹
Processor/AddAttributesBatch-16     1.085Ki ± 1%     1.086Ki ± 1%       ~ (p=1.000 n=10)
Processor/SetAttributesSimple-16      465.0 ± 0%       465.0 ± 0%       ~ (p=1.000 n=10) ¹
Processor/SetAttributesBatch-16     1.129Ki ± 1%     1.125Ki ± 1%       ~ (p=0.084 n=10)
LoggerNewRecord/5_attributes-16       0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
LoggerNewRecord/10_attributes-16      610.0 ± 0%       610.0 ± 0%       ~ (p=1.000 n=10) ¹
LoggerEnabled-16                      0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
LoggerProviderLogger-16               359.0 ± 6%       346.0 ± 3%       ~ (p=0.117 n=10)
WalkAttributes/1_attributes-16        0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
WalkAttributes/10_attributes-16       0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
WalkAttributes/100_attributes-16      0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
WalkAttributes/1000_attributes-16     0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
SetAddAttributes/SetAttributes-16     48.00 ± 0%       48.00 ± 0%       ~ (p=1.000 n=10) ¹
SetAddAttributes/AddAttributes-16     0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
SimpleProcessorOnEmit-16              0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=10) ¹
geomean                                          ²                 -0.27%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │   old.txt    │               new.txt               │
                                  │  allocs/op   │ allocs/op   vs base                 │
BatchProcessorOnEmit-16             0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/Simple-16                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/Batch-16                  1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/SetTimestampSimple-16     1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/SetTimestampBatch-16      1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/AddAttributesSimple-16    1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/AddAttributesBatch-16     1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/SetAttributesSimple-16    2.000 ± 0%     2.000 ± 0%       ~ (p=1.000 n=10) ¹
Processor/SetAttributesBatch-16     2.000 ± 0%     2.000 ± 0%       ~ (p=1.000 n=10) ¹
LoggerNewRecord/5_attributes-16     0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
LoggerNewRecord/10_attributes-16    4.000 ± 0%     4.000 ± 0%       ~ (p=1.000 n=10) ¹
LoggerEnabled-16                    0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
LoggerProviderLogger-16             1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
WalkAttributes/1_attributes-16      0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
WalkAttributes/10_attributes-16     0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
WalkAttributes/100_attributes-16    0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
WalkAttributes/1000_attributes-16   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
SetAddAttributes/SetAttributes-16   1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
SetAddAttributes/AddAttributes-16   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
SimpleProcessorOnEmit-16            0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
geomean                                        ²               +0.00%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean
```
This commit is contained in:
Robert Pająk
2024-09-13 06:35:01 +02:00
committed by GitHub
parent a475ee2d1b
commit 23f7b41e0a
16 changed files with 100 additions and 66 deletions
+17
View File
@@ -253,6 +253,23 @@ Rejected alternatives:
- [Add XYZ method to Logger](#add-xyz-method-to-logger)
- [Rename KeyValue to Attr](#rename-keyvalue-to-attr)
### Logger.Enabled
The `Enabled` method implements the [`Enabled` operation](https://opentelemetry.io/docs/specs/otel/logs/bridge-api/#enabled).
[`Context` associated with the `LogRecord`](https://opentelemetry.io/docs/specs/otel/context/)
is accepted as a `context.Context` method argument.
Calls to `Enabled` are supposed to be on the hot path and the list of arguments
can be extendend in future. Therefore, in order to reduce the number of heap
allocations and make it possible to handle new arguments, `Enabled` accepts
a `EnabledParameters` struct, defined in [logger.go](logger.go), as the second
method argument.
The `EnabledParameters` getters are returning values using the `(value, ok)`
idiom in order to indicate if the values were actually set by the caller or if
there are unspecified.
### noop package
The `go.opentelemetry.io/otel/log/noop` package provides
+2 -2
View File
@@ -87,10 +87,10 @@ func (l *logger) Emit(ctx context.Context, r log.Record) {
}
}
func (l *logger) Enabled(ctx context.Context, r log.Record) bool {
func (l *logger) Enabled(ctx context.Context, param log.EnabledParameters) bool {
var enabled bool
if del, ok := l.delegate.Load().(log.Logger); ok {
enabled = del.Enabled(ctx, r)
enabled = del.Enabled(ctx, param)
}
return enabled
}
+5 -3
View File
@@ -51,11 +51,12 @@ func TestLoggerConcurrentSafe(t *testing.T) {
ctx := context.Background()
var r log.Record
var param log.EnabledParameters
var enabled bool
for {
l.Emit(ctx, r)
enabled = l.Enabled(ctx, r)
enabled = l.Enabled(ctx, param)
select {
case <-stop:
@@ -103,16 +104,17 @@ 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) Enabled(context.Context, log.EnabledParameters) bool {
l.enabledN++
return true
}
func emitRecord(l log.Logger) {
ctx := context.Background()
var param log.EnabledParameters
var r log.Record
_ = l.Enabled(ctx, r)
_ = l.Enabled(ctx, param)
l.Emit(ctx, r)
}
+24 -6
View File
@@ -31,26 +31,26 @@ type Logger interface {
Emit(ctx context.Context, record Record)
// Enabled returns whether the Logger emits for the given context and
// record.
// param.
//
// The passed record is likely to be a partial record with only the
// bridge-relevant information being provided (e.g a record with only the
// The passed param is likely to be a partial record with only the
// bridge-relevant information being provided (e.g a param with only the
// Severity set). If a Logger needs more information than is provided, it
// is said to be in an indeterminate state (see below).
//
// The returned value will be true when the Logger will emit for the
// provided context and record, and will be false if the Logger will not
// provided context and param, and will be false if the Logger will not
// emit. The returned value may be true or false in an indeterminate state.
// An implementation should default to returning true for an indeterminate
// state, but may return false if valid reasons in particular circumstances
// exist (e.g. performance, correctness).
//
// The record should not be held by the implementation. A copy should be
// The param should not be held by the implementation. A copy should be
// made if the record needs to be held after the call returns.
//
// Implementations of this method need to be safe for a user to call
// concurrently.
Enabled(ctx context.Context, record Record) bool
Enabled(ctx context.Context, param EnabledParameters) bool
}
// LoggerOption applies configuration options to a [Logger].
@@ -129,3 +129,21 @@ func WithSchemaURL(schemaURL string) LoggerOption {
return config
})
}
// EnabledParameters represents payload for [Logger]'s Enabled method.
type EnabledParameters struct {
severity Severity
severitySet bool
}
// Severity returns the [Severity] level value, or [SeverityUndefined] if no value was set.
// The ok result indicates whether the value was set.
func (r *EnabledParameters) Severity() (value Severity, ok bool) {
return r.severity, r.severitySet
}
// SetSeverity sets the [Severity] level.
func (r *EnabledParameters) SetSeverity(level Severity) {
r.severity = level
r.severitySet = true
}
+6 -6
View File
@@ -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.EnabledParameters) bool
var defaultEnabledFunc = func(context.Context, log.Record) bool {
var defaultEnabledFunc = func(context.Context, log.EnabledParameters) 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.EnabledParameters) 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) Enabled(ctx context.Context, opts log.EnabledParameters) 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.
+12 -12
View File
@@ -65,18 +65,18 @@ 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
buildEnabledParameters func() log.EnabledParameters
isEnabled bool
}{
{
name: "the default option enables every log entry",
ctx: context.Background(),
buildRecord: func() log.Record {
return log.Record{}
buildEnabledParameters: func() log.EnabledParameters {
return log.EnabledParameters{}
},
isEnabled: true,
@@ -84,20 +84,20 @@ func TestLoggerEnabled(t *testing.T) {
{
name: "with everything disabled",
options: []Option{
WithEnabledFunc(func(context.Context, log.Record) bool {
WithEnabledFunc(func(context.Context, log.EnabledParameters) bool {
return false
}),
},
ctx: context.Background(),
buildRecord: func() log.Record {
return log.Record{}
buildEnabledParameters: func() log.EnabledParameters {
return log.EnabledParameters{}
},
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").Enabled(tt.ctx, tt.buildEnabledParameters())
assert.Equal(t, tt.isEnabled, e)
})
}
@@ -105,7 +105,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.Enabled(context.Background(), log.EnabledParameters{}))
}
func TestRecorderEmitAndReset(t *testing.T) {
@@ -158,7 +158,7 @@ func TestRecorderConcurrentSafe(t *testing.T) {
defer wg.Done()
nr := r.Logger("test")
nr.Enabled(context.Background(), log.Record{})
nr.Enabled(context.Background(), log.EnabledParameters{})
nr.Emit(context.Background(), log.Record{})
r.Result()
+1 -1
View File
@@ -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) Enabled(context.Context, log.EnabledParameters) bool { return false }