Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0e1e016
Add Complex Processing to Logs Supplementary Guidelines
pellared Feb 10, 2025
c471e42
Content
pellared Feb 10, 2025
eebacd3
Remove unecessary
pellared Feb 10, 2025
e653f24
More use cases
pellared Feb 10, 2025
8ca7841
Add changelog entry
pellared Feb 10, 2025
dd9c867
Merge branch 'main' into complex-log-processing
pellared Feb 10, 2025
75d9aa2
markdownlint: inline ignore no-hard-tabs
pellared Feb 10, 2025
a5b4dd7
Merge branch 'main' into complex-log-processing
pellared Feb 10, 2025
fa01c47
Update supplementary-guidelines.md
pellared Feb 10, 2025
5c96c61
Update specification/logs/supplementary-guidelines.md
pellared Feb 10, 2025
f1145c7
Update supplementary-guidelines.md
pellared Feb 10, 2025
545dc53
Address feedback
pellared Feb 11, 2025
b2a2459
Merge branch 'main' into complex-log-processing
pellared Feb 11, 2025
b7d5f07
Add note
pellared Feb 11, 2025
3add16d
Make the Go snippets to compile
pellared Feb 11, 2025
98224d0
Add RedactTokensProcessor
pellared Feb 11, 2025
5595830
Add setup example
pellared Feb 11, 2025
fd89f0b
Add comments
pellared Feb 11, 2025
83aef47
Fix language
pellared Feb 11, 2025
99d0264
Fixes
pellared Feb 11, 2025
67a20a1
TOC
pellared Feb 11, 2025
a277f52
Fix hyperlink
pellared Feb 11, 2025
f639627
Update supplementary-guidelines.md
pellared Feb 11, 2025
774e4eb
Update specification/logs/supplementary-guidelines.md
pellared Feb 11, 2025
b6fb700
Handle SeverityUndefined
pellared Feb 11, 2025
764a7cc
Merge branch 'main' into complex-log-processing
pellared Feb 12, 2025
834cc21
Merge branch 'main' into complex-log-processing
pellared Feb 13, 2025
0790167
Apply suggestions from code review
pellared Feb 13, 2025
ff92b75
Update supplementary-guidelines.md
pellared Feb 13, 2025
b2fdbc0
Update specification/logs/sdk.md
pellared Feb 13, 2025
97ebca3
Update supplementary-guidelines.md
pellared Feb 14, 2025
c4cc314
Update supplementary-guidelines.md
pellared Feb 14, 2025
288f2b5
Update sdk.md
pellared Feb 14, 2025
e326c0c
Update supplementary-guidelines.md
pellared Feb 14, 2025
b5b83aa
Update supplementary-guidelines.md
pellared Feb 14, 2025
ece2df1
Merge branch 'main' into complex-log-processing
pellared Feb 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ release.

### Supplementary Guidelines

- Add Complex Processing to Logs Supplementary Guidelines.
([#4407](https://github.com/open-telemetry/opentelemetry-specification/pull/4407))

### OTEPs

## v1.41.0 (2025-01-21)
Expand Down
4 changes: 4 additions & 0 deletions specification/logs/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ components in the SDK:
+-----+------------------------+
```

Please see [Supplementary Guidelines](./supplementary-guidelines.md#complex-log-processing)
for more information on how to setup complex log record processing
(filtering, fan-out, routing).

### LogRecordProcessor operations

#### OnEmit
Expand Down
89 changes: 89 additions & 0 deletions specification/logs/supplementary-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ extra requirements to the existing specifications.
* [Context](#context)
+ [Implicit Context Injection](#implicit-context-injection)
+ [Explicit Context Injection](#explicit-context-injection)
* [Complex Processing](#complex-processing)

<!-- tocstop -->

Expand Down Expand Up @@ -117,4 +118,92 @@ See
[an example](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/aeb198d6de25588afef49545cfa06533d0e67f1d/bridges/otelzap/core.go#L194-L244)
of how it can be done for zap logging library for Go.

### Complex Processing

As rule of thumb, users of [Logs SDK](sdk.md) are advised to have a simple
processing pipeline that simply exports the log records to the Collector
and use its processing capabilities if necessary. Doing so decouples the
application code from the telemetry processing.

However, in some cases (like mobile devices, IoT, serverless, performance or cost
tuning, legacy systems) using a Collector is not feasible. In these cases, users are able to use
different [structural design patterns](https://refactoring.guru/design-patterns/structural-patterns)
to achieve complex log processing pipelines.

Let's look at some simple examples written in Go.

<!-- markdownlint-disable no-hard-tabs -->

Filtering can be achieved by [decorating](https://refactoring.guru/design-patterns/decorator)
a processor.

```go
// SeverityProcessor decorates a processor to filter out log records
// that severity is below given threshold.
type SeverityProcessor struct {
sdklog.Processor
Min log.Severity
}

// OnEmit passes ctx and record to the sdklog.Processor that p wraps if the
// severity of record is greater than or equal to p.Min. Otherwise, record is
// dropped.
func (p *SeverityProcessor) OnEmit(ctx context.Context, record *sdklog.Record) error {
if record.Severity() < p.Min {
return nil
}
return p.Processor.OnEmit(ctx, record)
}
```

Supporting multiple processing pipelines can be achieved by
[composing](https://refactoring.guru/design-patterns/composite) processors.

```go
// FanoutProcessor composes multiple processors so that they are isolated.
// Each processor operates on a deep copy of the record.
type FanoutProcessor struct {
Processors []sdklog.Processor
}

// OnEmit passes ctx and a clone of record to the each wrapped sdklog.Processor.
func (p *FanoutProcessor) OnEmit(ctx context.Context, record *sdklog.Record) error {
var rErr error
for _, proc := range p.Processors {
r := record.Clone()
if err := proc.OnEmit(ctx, &r); err != nil {
rErr = errors.Join(rErr, err)
}
}
return rErr
}

// Implementation of ForceFlush and Shutdown is left for the reader.
```

Other capabilities, such as routing, attributes can be implemented using
different combinations of wrapping and composing of processors.

```go

// LogEventRouteProcessor splits the log record processing from event record processing.
type LogEventRouteProcessor struct {
LogProcessor sdklog.Processor
EventProcessor sdklog.Processor
}

// OnEmit calls EventProcessor if record has non-empty event name.
// Otherwise, it calls LogProcessor.
func (p *LogEventRouteProcessor) OnEmit(ctx context.Context, record *sdklog.Record) error {
if record.EventName() != "" {
return p.EventProcessor.OnEmit(ctx, record)
}
return p.LogProcessor.OnEmit(ctx, record)
}

// Implementation of ForceFlush and Shutdown is left for the reader.
```

<!-- markdownlint-enable no-hard-tabs -->

- [OTEP0150 Logging Library SDK Prototype Specification](../../oteps/logs/0150-logging-library-sdk.md)
Loading