Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decoupling Event API from Logs API #3167

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
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
127 changes: 108 additions & 19 deletions specification/logs/event-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,30 +47,120 @@ to the [semantic conventions for Events](./semantic_conventions/events.md).
Unlike the [Logs Bridge API](./bridge-api.md), application developers and
instrumentation authors are encouraged to call this API directly.

The Event API consist of these main classes:

* EventLoggerProvider is the entry point of the API. It provides access to Loggers.
* EventLogger is the class responsible for
emitting [Events](./data-model.md#log-and-event-record-definition) as
LogRecords.

EventLoggerProvider/EventLogger are analogous to TracerProvider/Tracer.

```mermaid
graph TD
A[EventLoggerProvider] -->|Get| B(EventLogger)
B --> C(Event)
```

## EventLoggerProvider

`EventLogger`s can be accessed with a `EventLoggerProvider`.

In implementations of the API, the EventLoggerProvider is expected to be the stateful
object that holds any configuration.

Normally, the EventLoggerProvider is expected to be accessed from a central place.
Thus, the API SHOULD provide a way to set/register and access a global default
EventLoggerProvider.

Notwithstanding any global EventLoggerProvider, some applications may want to or have
to use multiple EventLoggerProvider instances, e.g. to have different configuration
(like [LogRecordProcessors](sdk.md#logrecordprocessor)) for each (and
consequently for the EventLoggers obtained from them), or because it's easier with
dependency injection frameworks. Thus, implementations of EventLoggerProvider SHOULD
allow creating an arbitrary number of instances.

### EventLoggerProvider operations

The EventLoggerProvider MUST provide the following functions:

* Get an EventLogger

#### Get a EventLogger

This API MUST accept the following parameters:

- `name` (required): This name SHOULD uniquely identify the [instrumentation scope](../glossary.md#instrumentation-scope),
such as the [instrumentation library](../glossary.md#instrumentation-library)
(e.g. `io.opentelemetry.contrib.mongodb`), package, module or class name.
If an application or library has built-in OpenTelemetry instrumentation, both
[Instrumented library](../glossary.md#instrumented-library) and
[Instrumentation library](../glossary.md#instrumentation-library) may refer to
the same library. In that scenario, the `name` denotes a module name or component
name within that library or application. In case an invalid name
(null or empty string) is specified, a working Logger implementation MUST be
returned as a fallback rather than returning null or throwing an exception, its
`name` property SHOULD be set to an empty string, and a message reporting that
the specified value is invalid SHOULD be logged. A library implementing the
OpenTelemetry API may also ignore this name and return a default instance for
all calls, if it does not support "named" functionality (e.g. an implementation
which is not even observability-related). A LoggerProvider could also return a
no-op Logger here if application owners configure the SDK to suppress telemetry
produced by this library.
- `event_domain` (required): Specifies the domain of emitted events, used to set the `event.domain`
attribute.
- `version` (optional): Specifies the version of the instrumentation scope if
the scope has a version (e.g. a library version). Example value: 1.0.0.
- `schema_url` (optional): Specifies the Schema URL that should be recorded in
the emitted telemetry.
- `include_trace_context` (optional): Specifies whether the Trace Context should
automatically be passed on to the events emitted by the EventLogger. This
SHOULD be true by default.
- `attributes` (optional): Specifies the instrumentation scope attributes to
associate with emitted telemetry.

EventLoggers are identified by `name`, `event_domain`, `version`, and `schema_url` fields. When more
than one `Logger` of the same `name`, `event_domain`, `version`, and `schema_url` is created, it
is unspecified whether or under which conditions the same or different `EventLogger`
instances are returned. It is a user error to create EventLoggers with different
attributes but the same identity.

The term *identical* applied to EventLoggers describes instances where all
identifying fields are equal. The term *distinct* applied to EventLoggers describes
instances where at least one identifying field has a different value.

Implementations MUST NOT require users to repeatedly obtain an EventLogger again with
the same name+event_domain+version+schema_url+include_trace_context+attributes
to pick up configuration changes. This can be achieved either by allowing to
work with an outdated configuration or by ensuring that new configuration
applies also to previously returned EventLoggers.

Note: This could, for example, be implemented by storing any mutable
configuration in the `EventLoggerProvider` and having `EventLogger` implementation objects
have a reference to the `EventLoggerProvider` from which they were obtained.
If configuration must be stored per-EventLogger (such as disabling a certain `EventLogger`),
the `EventLogger` could, for example, do a look-up with its name+event_domain+version+schema_url+include_trace_context+attributes
in a map in the `EventLoggerProvider`, or the `EventLoggerProvider` could maintain a registry
of all returned `EventLogger`s and actively update their configuration if it changes.

The effect of associating a Schema URL with a `EventLogger` MUST be that the telemetry
emitted using the `EventLogger` will be associated with the Schema URL, provided that
the emitted data format is capable of representing such association.

## EventLogger

The `EventLogger` is the entrypoint of the Event API, and is responsible for
emitting `Events` as `LogRecords`.
The `EventLogger` is responsible for emitting `Event`s as `LogRecord`s

Note that `EventLogger`s should not be responsible for configuration. This should be
the responsibility of the `EventLoggerProvider` instead.

### EventLogger Operations

The `EventLogger` MUST provide functions to:

#### Create EventLogger

New `EventLogger` instances are created though a constructor or factory method
on `EventLogger`.

**Parameters:**

* `logger` - the delegate [Logger](./bridge-api.md#logger) used to emit `Events`
as `LogRecords`.
* `event_domain` - the domain of emitted events, used to set the `event.domain`
attribute.

#### Emit Event

Emit a `LogRecord` representing an `Event` to the delegate `Logger`.
Emit a `LogRecord` representing an `Event`.

This function MAY be named `logEvent`.

Expand All @@ -80,13 +170,12 @@ This function MAY be named `logEvent`.
attribute with the key `event.name`. Care MUST be taken by the implementation
to not override or delete this attribute while the Event is emitted to
preserve its identity.
* `logRecord` - the [LogRecord](./bridge-api.md#logrecord) representing the Event.
* `event` - the [LogRecord](./api.md#logrecord) representing the Event.

**Implementation Requirements:**

The implementation MUST [emit](./bridge-api.md#emit-logrecord) the `logRecord` to
the `logger` specified when [creating the EventLogger](#create-eventlogger)
after making the following changes:
The implementation MUST [emit](./api.md#emit-logrecord) the event `LogRecord` after
making the following changes:

* The `event_domain` specified
when [creating the EventLogger](#create-eventlogger) MUST be set as
Expand Down