Skip to content

Commit a027f11

Browse files
authored
chore: Update Logs API design doc (#6206)
There were some changes in the design that should be updated. Most importantly: - Logs Bridge API -> Logs API that can be called directly: #6167 - addition of converting functions: #6180 - event support: #6187
1 parent ae7ac48 commit a027f11

File tree

1 file changed

+36
-35
lines changed

1 file changed

+36
-35
lines changed

log/DESIGN.md

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
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

88
The 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/)
1414
with an intuitive and user friendly design.
1515
Performance 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)
4444
is defined as `LoggerProvider` interface in [provider.go](provider.go).
4545

4646
The 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

5656
The required `name` parameter is accepted as a `string` method argument.
5757

5858
The `LoggerOption` options are defined to support optional parameters.
5959

6060
Implementation 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)
8282
is defined as `Logger` interface in [logger.go](logger.go).
8383

8484
The 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/)
9595
is accepted as a `context.Context` method argument.
9696

9797
Calls to `Emit` are supposed to be on the hot path.
9898
Therefore, 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),
100100
is 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
115115
func (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)
119127
is 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

223231
Implementation 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/)
259267
is accepted as a `context.Context` method argument.
@@ -271,7 +279,7 @@ where `Enabled` is called.
271279
### noop package
272280

273281
The `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

320328
The 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/).
323331
and we cannot expect the Go team to make `slog` compliant with it.
324332

325333
The 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:
423431
type 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

432442
The 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.
508518
Especially when having getter and setter methods, setting one value
509519
when the other is already set would be unpleasant.
510520

511-
## Reuse attribute package
521+
### Reuse attribute package
512522

513523
It 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.
523533
Therefore, we define new types representing the abstract types defined
524534
in 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

528538
Methods of [`slog.Record`](https://pkg.go.dev/log/slog#Record)
529539
have 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

598600
During 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

605608
As for map item semantics, this type is a key-value pair, not an attribute.
606609
Naming the type as `Attr` would convey semantical meaning
607610
that 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.
610613
We plan to implement bridges for the most popular logging libraries ourselves.
611614
Given we will all have the context needed to disambiguate these overlapping
612615
names, developers' confusion should not be an issue.
@@ -615,10 +618,8 @@ For bridges not developed by us,
615618
developers will likely look at our existing bridges for inspiration.
616619
Our 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

Comments
 (0)