1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-08-10 22:31:50 +02:00
Files
opentelemetry-go/log/logger.go
Robert Pająk 1ee7c79b73 sdk/log: Add FilterProcessor and EnabledParameters (#6317)
Per
https://github.com/open-telemetry/opentelemetry-go/pull/6271#issuecomment-2657554647

> We agreed that we can move `FilterProcessor` directly to `sdk/log` as
Logs SDK does not look to be stabilized soon.

- Add the possibility to filter based on the resource and scope which is
available for the SDK. The scope information is the most important as it
gives the possibility to e.g. filter out logs emitted for a given
logger. Thus e.g.
https://github.com/open-telemetry/opentelemetry-specification/issues/4364
is not necessary. See
https://github.com/open-telemetry/opentelemetry-specification/pull/4290#discussion_r1927546170
for more context.
- It is going be an example for
https://github.com/open-telemetry/opentelemetry-specification/issues/4363

There is a little overhead (IMO totally acceptable) because of data
transformation. Most importantly, there is no new heap allocation.

```
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/log
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
                 │   old.txt   │                 new.txt                  │
                 │   sec/op    │     sec/op      vs base                  │
LoggerEnabled-20   4.589n ± 1%   319.750n ± 16%  +6867.75% (p=0.000 n=10)

                 │   old.txt    │             new.txt             │
                 │     B/op     │     B/op       vs base          │
LoggerEnabled-20   0.000Ki ± 0%   1.093Ki ± 13%  ? (p=0.000 n=10)

                 │  old.txt   │            new.txt             │
                 │ allocs/op  │ allocs/op   vs base            │
LoggerEnabled-20   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal
```

`Logger.Enabled` is still more efficient than `Logger.Emit` (benchmarks
from https://github.com/open-telemetry/opentelemetry-go/pull/6315).

```
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/log
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkLoggerEmit/5_attributes-20               559934              2391 ns/op           39088 B/op          1 allocs/op
BenchmarkLoggerEmit/10_attributes-20             1000000              5910 ns/op           49483 B/op          5 allocs/op
BenchmarkLoggerEnabled-20                        1605697               968.7 ns/op          1272 B/op          0 allocs/op
PASS
ok      go.opentelemetry.io/otel/sdk/log        10.789s
```

Prior art:
- https://github.com/open-telemetry/opentelemetry-go/pull/6271
- https://github.com/open-telemetry/opentelemetry-go/pull/6286

I also created for tracking purposes:
- https://github.com/open-telemetry/opentelemetry-go/issues/6328
2025-02-18 22:35:14 +01:00

141 lines
4.5 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package log // import "go.opentelemetry.io/otel/log"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/log/embedded"
)
// Logger emits log records.
//
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type Logger interface {
// Users of the interface can ignore this. This embedded type is only used
// by implementations of this interface. See the "API Implementations"
// section of the package documentation for more information.
embedded.Logger
// Emit emits a log record.
//
// The record may be held by the implementation. Callers should not mutate
// the record after passed.
//
// Implementations of this method need to be safe for a user to call
// concurrently.
Emit(ctx context.Context, record Record)
// Enabled returns whether the Logger emits for the given context and
// param.
//
// This is useful for users that want to know if a [Record]
// will be processed or dropped before they perform complex operations to
// construct the [Record].
//
// The passed param is likely to be a partial record 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 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 param should not be held by the implementation. A copy should be
// made if the param 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, param EnabledParameters) bool
}
// LoggerOption applies configuration options to a [Logger].
type LoggerOption interface {
// applyLogger is used to set a LoggerOption value of a LoggerConfig.
applyLogger(LoggerConfig) LoggerConfig
}
// LoggerConfig contains options for a [Logger].
type LoggerConfig struct {
// Ensure forward compatibility by explicitly making this not comparable.
noCmp [0]func() //nolint: unused // This is indeed used.
version string
schemaURL string
attrs attribute.Set
}
// NewLoggerConfig returns a new [LoggerConfig] with all the options applied.
func NewLoggerConfig(options ...LoggerOption) LoggerConfig {
var c LoggerConfig
for _, opt := range options {
c = opt.applyLogger(c)
}
return c
}
// InstrumentationVersion returns the version of the library providing
// instrumentation.
func (cfg LoggerConfig) InstrumentationVersion() string {
return cfg.version
}
// InstrumentationAttributes returns the attributes associated with the library
// providing instrumentation.
func (cfg LoggerConfig) InstrumentationAttributes() attribute.Set {
return cfg.attrs
}
// SchemaURL returns the schema URL of the library providing instrumentation.
func (cfg LoggerConfig) SchemaURL() string {
return cfg.schemaURL
}
type loggerOptionFunc func(LoggerConfig) LoggerConfig
func (fn loggerOptionFunc) applyLogger(cfg LoggerConfig) LoggerConfig {
return fn(cfg)
}
// WithInstrumentationVersion returns a [LoggerOption] that sets the
// instrumentation version of a [Logger].
func WithInstrumentationVersion(version string) LoggerOption {
return loggerOptionFunc(func(config LoggerConfig) LoggerConfig {
config.version = version
return config
})
}
// WithInstrumentationAttributes returns a [LoggerOption] that sets the
// instrumentation attributes of a [Logger].
//
// The passed attributes will be de-duplicated.
func WithInstrumentationAttributes(attr ...attribute.KeyValue) LoggerOption {
return loggerOptionFunc(func(config LoggerConfig) LoggerConfig {
config.attrs = attribute.NewSet(attr...)
return config
})
}
// WithSchemaURL returns a [LoggerOption] that sets the schema URL for a
// [Logger].
func WithSchemaURL(schemaURL string) LoggerOption {
return loggerOptionFunc(func(config LoggerConfig) LoggerConfig {
config.schemaURL = schemaURL
return config
})
}
// EnabledParameters represents payload for [Logger]'s Enabled method.
type EnabledParameters struct {
Severity Severity
}