1- # Logs Bridge API
1+ # Logs API
22
33## Abstract
44
55` go.opentelemetry.io/otel/log ` provides
6- [ Logs Bridge API] ( https://opentelemetry.io/docs/specs/otel/logs/bridge- api/ ) .
6+ [ Logs API] ( https://opentelemetry.io/docs/specs/otel/logs/api/ ) .
77
88The prototype was created in
99[ #4725 ] ( https://github.com/open-telemetry/opentelemetry-go/pull/4725 ) .
1010
1111## Background
1212
13- The key challenge is to create a performant API compliant with the [ specification] ( https://opentelemetry.io/docs/specs/otel/logs/bridge- api/ )
13+ The key challenge is to create a performant API compliant with the [ specification] ( https://opentelemetry.io/docs/specs/otel/logs/api/ )
1414with an intuitive and user friendly design.
1515Performance is seen as one of the most important characteristics of logging libraries in Go.
1616
@@ -40,7 +40,7 @@ Rejected alternative:
4040
4141### LoggerProvider
4242
43- The [ ` LoggerProvider ` abstraction] ( https://opentelemetry.io/docs/specs/otel/logs/bridge- api/#loggerprovider )
43+ The [ ` LoggerProvider ` abstraction] ( https://opentelemetry.io/docs/specs/otel/logs/api/#loggerprovider )
4444is defined as ` LoggerProvider ` interface in [ provider.go] ( provider.go ) .
4545
4646The specification may add new operations to ` LoggerProvider ` .
@@ -51,15 +51,15 @@ This approach is already used in Trace API and Metrics API.
5151
5252#### LoggerProvider.Logger
5353
54- The ` Logger ` method implements the [ ` Get a Logger ` operation] ( https://opentelemetry.io/docs/specs/otel/logs/bridge- api/#get-a-logger ) .
54+ The ` Logger ` method implements the [ ` Get a Logger ` operation] ( https://opentelemetry.io/docs/specs/otel/logs/api/#get-a-logger ) .
5555
5656The required ` name ` parameter is accepted as a ` string ` method argument.
5757
5858The ` LoggerOption ` options are defined to support optional parameters.
5959
6060Implementation requirements:
6161
62- - The [ specification requires] ( https://opentelemetry.io/docs/specs/otel/logs/bridge- api/#concurrency-requirements )
62+ - The [ specification requires] ( https://opentelemetry.io/docs/specs/otel/logs/api/#concurrency-requirements )
6363 the method to be safe to be called concurrently.
6464
6565- The method should use some default name if the passed name is empty
@@ -78,7 +78,7 @@ Rejected alternative:
7878
7979### Logger
8080
81- The [ ` Logger ` abstraction] ( https://opentelemetry.io/docs/specs/otel/logs/bridge- api/#logger )
81+ The [ ` Logger ` abstraction] ( https://opentelemetry.io/docs/specs/otel/logs/api/#logger )
8282is defined as ` Logger ` interface in [ logger.go] ( logger.go ) .
8383
8484The specification may add new operations to ` Logger ` .
@@ -89,14 +89,14 @@ This approach is already used in Trace API and Metrics API.
8989
9090### Logger.Emit
9191
92- The ` Emit ` method implements the [ ` Emit a LogRecord ` operation] ( https://opentelemetry.io/docs/specs/otel/logs/bridge- api/#emit-a-logrecord ) .
92+ The ` Emit ` method implements the [ ` Emit a LogRecord ` operation] ( https://opentelemetry.io/docs/specs/otel/logs/api/#emit-a-logrecord ) .
9393
9494[ ` Context ` associated with the ` LogRecord ` ] ( https://opentelemetry.io/docs/specs/otel/context/ )
9595is accepted as a ` context.Context ` method argument.
9696
9797Calls to ` Emit ` are supposed to be on the hot path.
9898Therefore, in order to reduce the number of heap allocations,
99- the [ ` LogRecord ` abstraction] ( https://opentelemetry.io/docs/specs/otel/logs/bridge- api/#emit-a-logrecord ) ,
99+ the [ ` LogRecord ` abstraction] ( https://opentelemetry.io/docs/specs/otel/logs/api/#emit-a-logrecord ) ,
100100is defined as ` Record ` struct in [ record.go] ( record.go ) .
101101
102102[ ` Timestamp ` ] ( https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-timestamp )
@@ -115,6 +115,14 @@ func (r *Record) ObservedTimestamp() time.Time
115115func (r *Record) SetObservedTimestamp(t time.Time)
116116```
117117
118+ [`EventName`](https:// opentelemetry.io/docs/specs/otel/logs/data-model/#field-eventname)
119+ is accessed using following methods:
120+
121+ ```go
122+ func (r *Record) EventName() string
123+ func (r *Record) SetEventName(s string)
124+ ```
125+
118126[`SeverityNumber`](https:// opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber)
119127is accessed using following methods:
120128
@@ -222,13 +230,13 @@ after the call (even when the documentation says that the caller must not do it)
222230
223231Implementation requirements:
224232
225- - The [specification requires](https:// opentelemetry.io/docs/specs/otel/logs/bridge- api/#concurrency-requirements)
233+ - The [specification requires](https:// opentelemetry.io/docs/specs/otel/logs/api/#concurrency-requirements)
226234 the method to be safe to be called concurrently.
227235
228236- The method must not interrupt the record processing if the context is canceled
229237 per ["ignoring context cancellation" guideline](../CONTRIBUTING.md#ignoring-context-cancellation).
230238
231- - The [specification requires](https:// opentelemetry.io/docs/specs/otel/logs/bridge- api/#emit-a-logrecord)
239+ - The [specification requires](https:// opentelemetry.io/docs/specs/otel/logs/api/#emit-a-logrecord)
232240 use the current time as observed timestamp if the passed is empty.
233241
234242- The method should handle the trace context passed via `ctx` argument in order to meet the
@@ -253,7 +261,7 @@ Rejected alternatives:
253261
254262### Logger.Enabled
255263
256- The `Enabled` method implements the [`Enabled` operation](https:// opentelemetry.io/docs/specs/otel/logs/bridge- api/#enabled).
264+ The `Enabled` method implements the [`Enabled` operation](https:// opentelemetry.io/docs/specs/otel/logs/api/#enabled).
257265
258266[`Context` associated with the `LogRecord`](https:// opentelemetry.io/docs/specs/otel/context/)
259267is accepted as a `context.Context` method argument.
@@ -271,7 +279,7 @@ where `Enabled` is called.
271279### noop package
272280
273281The `go.opentelemetry.io/otel/log/noop` package provides
274- [Logs Bridge API No-Op Implementation](https:// opentelemetry.io/docs/specs/otel/logs/noop/).
282+ [Logs API No-Op Implementation](https:// opentelemetry.io/docs/specs/otel/logs/noop/).
275283
276284### Trace context correlation
277285
@@ -319,7 +327,7 @@ nor any other logging library.
319327
320328The API needs to evolve orthogonally to `slog`.
321329
322- `slog` is not compliant with the [Logs Bridge API](https:// opentelemetry.io/docs/specs/otel/logs/bridge- api/).
330+ `slog` is not compliant with the [Logs API](https:// opentelemetry.io/docs/specs/otel/logs/api/).
323331and we cannot expect the Go team to make `slog` compliant with it.
324332
325333The interoperability can be achieved using [a log bridge](https:// opentelemetry.io/docs/specs/otel/glossary/#log-appender--bridge).
@@ -423,10 +431,12 @@ One of the proposals[^6] was to have `Record` as a simple struct:
423431type Record struct {
424432 Timestamp time.Time
425433 ObservedTimestamp time.Time
434+ EventName string
426435 Severity Severity
427436 SeverityText string
428437 Body Value
429438 Attributes []KeyValue
439+ }
430440```
431441
432442The bridge implementations could use [ ` sync.Pool ` ] ( https://pkg.go.dev/sync#Pool )
@@ -508,7 +518,7 @@ It should be more user friendly to have them separated.
508518Especially when having getter and setter methods, setting one value
509519when the other is already set would be unpleasant.
510520
511- ## Reuse attribute package
521+ ### Reuse attribute package
512522
513523It was tempting to reuse the existing
514524[ https://pkg.go.dev/go.opentelemetry.io/otel/attribute ] package
@@ -523,7 +533,7 @@ has anything in common with a common attribute value.
523533Therefore, we define new types representing the abstract types defined
524534in the [ Logs Data Model] ( https://opentelemetry.io/docs/specs/otel/logs/data-model/#definitions-used-in-this-document ) .
525535
526- ## Mix receiver types for Record
536+ ### Mix receiver types for Record
527537
528538Methods of [ ` slog.Record ` ] ( https://pkg.go.dev/log/slog#Record )
529539have different receiver types.
@@ -577,17 +587,9 @@ we decided to use pointer receivers for all `Record` methods.
577587
578588### Add XYZ method to Logger
579589
580- The ` Logger` does not have methods like ` Enabled` , ` SetSeverity` , etc.
581- as the Bridge API needs to follow (be compliant with)
582- the [specification](https://opentelemetry.io/docs/specs/otel/logs/bridge-api/)
583-
584- Moreover, the Bridge API is intended to be used to implement bridges.
585- Applications should not use it directly. The applications should use logging packages
586- such as [` slog` ](https://pkg.go.dev/log/slog),
587- [` logrus` ](https://pkg.go.dev/github.com/sirupsen/logrus),
588- [` zap` ](https://pkg.go.dev/go.uber.org/zap),
589- [` zerolog` ](https://pkg.go.dev/github.com/rs/zerolog),
590- [` logr` ](https://pkg.go.dev/github.com/go-logr/logr).
590+ The ` Logger ` does not have methods like ` SetSeverity ` , etc.
591+ as the Logs API needs to follow (be compliant with)
592+ the [ specification] ( https://opentelemetry.io/docs/specs/otel/logs/api/ )
591593
592594### Rename KeyValue to Attr
593595
@@ -597,16 +599,17 @@ the OpenTelemetry parlance.
597599
598600During the discussion we agreed to keep the ` KeyValue ` name.
599601
600- The type is used in two semantics:
602+ The type is used in multiple semantics:
601603
602- - as a log attribute
603- - as a map item
604+ - as a log attribute,
605+ - as a map item,
606+ - as a log record Body.
604607
605608As for map item semantics, this type is a key-value pair, not an attribute.
606609Naming the type as ` Attr ` would convey semantical meaning
607610that would not be correct for a map.
608611
609- We expect that most of the Bridge API users will be OpenTelemetry contributors.
612+ We expect that most of the Logs API users will be OpenTelemetry contributors.
610613We plan to implement bridges for the most popular logging libraries ourselves.
611614Given we will all have the context needed to disambiguate these overlapping
612615names, developers' confusion should not be an issue.
@@ -615,10 +618,8 @@ For bridges not developed by us,
615618developers will likely look at our existing bridges for inspiration.
616619Our correct use of these types will be a reference to them.
617620
618- At last, we could consider a design defining both types: ` KeyValue` and ` Attr` .
619- However, in this approach we would need have factory functions for both types.
620- It would make the API surface unnecessarily big,
621- and we may even have problems naming the functions.
621+ At last, we provide ` ValueFromAttribute ` and ` KeyValueFromAttribute `
622+ to offer reuse of ` attribute.Value ` and ` attribute.KeyValue ` .
622623
623624[ ^ 1 ] : [ Handle structured body and attributes] ( https://github.com/pellared/opentelemetry-go/pull/7 )
624625[ ^ 2 ] : Jonathan Amsterdam, [ The Go Blog: Structured Logging with slog] ( https://go.dev/blog/slog )
0 commit comments