Skip to content

Commit

Permalink
Add Provider to the Event API (open-telemetry#3878)
Browse files Browse the repository at this point in the history
Fixes
open-telemetry#3086

## Changes

The Event API will be used by instrumentations to generate events.
Currently, the API takes an instance of a logger as a direct dependency.
This means that instrumentations would need to be aware of the Log API,
which is in conflict with the intent of using the Log API only to bridge
logging frameworks. Furthermore, each instrumentation would need to
construct an instance of an EventLogger, which is also inconsistent with
the pattern of using a globally-registered provider.

This PR adds the `EventLoggerProvider` class to the API, making it
consistent with other APIs.
  • Loading branch information
martinkuba authored Mar 12, 2024
1 parent 7c173f2 commit 5bd099a
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 57 deletions.
2 changes: 1 addition & 1 deletion specification/logs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ processor.

These are logs generated by various infrastructure components, such as
Kubernetes events (if you are wondering why events are discussed in the context
of logs see [Event API Overview](./event-api.md#overview)). Like system logs, the
of logs see [Event API Data model](./event-api.md#data-model)). Like system logs, the
infrastructure logs lack a trace context and can be enriched by the resource
context - information about the node, pod, container, etc.

Expand Down
114 changes: 58 additions & 56 deletions specification/logs/event-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,25 @@

<!-- toc -->

- [Overview](#overview)
- [Data model](#data-model)
- [EventLoggerProvider](#eventloggerprovider)
* [EventLoggerProvider operations](#eventloggerprovider-operations)
+ [Get an EventLogger](#get-an-eventlogger)
- [EventLogger](#eventlogger)
* [EventLogger Operations](#eventlogger-operations)
+ [Create EventLogger](#create-eventlogger)
+ [Emit Event](#emit-event)
- [Optional and required parameters](#optional-and-required-parameters)

<!-- tocstop -->

</details>

## Overview
The Event API consists of these main components:

* [EventLoggerProvider](#eventloggerprovider) is the entry point of the API. It provides access to `EventLogger`s.
* [EventLogger](#eventlogger) is the component responsible for emitting events.

## Data model

Wikipedia’s [definition of log file](https://en.wikipedia.org/wiki/Log_file):

Expand All @@ -37,17 +44,56 @@ have `Payloads` that conform to the same schema, which assists in analysis in
observability platforms. Events are described in more detail in
the [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/events.md).

While the logging space has a diverse legacy with many existing logging
libraries in different languages, there is not ubiquitous alignment with
OpenTelemetry events. In some logging libraries, producing records shaped as
OpenTelemetry events is clunky or error-prone.

The Event API offers convenience methods
for [emitting LogRecords](./bridge-api.md#emit-a-logrecord) that conform
to the [semantic conventions for Events](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/events.md).
Unlike the [Logs Bridge API](./bridge-api.md), application developers and
instrumentation authors are encouraged to call this API directly.

## EventLoggerProvider

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

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`.

### EventLoggerProvider operations

The `EventLoggerProvider` MUST provide the following functions:

* Get an `EventLogger`

#### Get an EventLogger

This API MUST accept the following parameters:

* `name`: This name uniquely identifies 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.

* `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.

* `attributes` (optional): Specifies the instrumentation scope attributes to
associate with emitted telemetry. This API MUST be structured to accept a
variable number of attributes, including none.

`EventLogger`s are identified by `name`, `version`, and `schema_url` fields. When more
than one `EventLogger` of the same `name`, `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 `EventLogger`s with different
`attributes` but the same identity.

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
Expand All @@ -57,21 +103,9 @@ emitting `Events` as `LogRecord`s.

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 `LogRecord`s.

#### Emit Event

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

This function MAY be named `logEvent`.
The effect of calling this API is to emit an `Event` to the processing pipeline.

**Parameters:**

Expand All @@ -85,38 +119,6 @@ This function MAY be named `logEvent`.
additional details about the Event which are not part of the
well-defined `Payload`.

**Implementation Requirements:**

The implementation MUST use the parameters
to [emit a logRecord](./bridge-api.md#emit-a-logrecord) using the `logger`
specified when [creating the EventLogger](#create-eventlogger) as follows:

* The `Name` MUST be used to set
the `event.name` [Attribute](./data-model.md#field-attributes). If
the `Attributes` provided by the user contain an `event.name` attribute the
value provided in the `Name` takes precedence.
* If provided by the user, the `Payload` MUST be used to set
the [Body](./data-model.md#field-body). If not provided, `Body` MUST not be
set.
* If provided by the user, the `Timestamp` MUST be used to set
the [Timestamp](./data-model.md#field-timestamp). If not provided, `Timestamp`
MUST be set to the current time when [emit](#emit-event) was called.
* The [Observed Timestamp](./data-model.md#field-observedtimestamp) MUST not be
set. (NOTE: [emit a logRecord](./bridge-api.md#emit-a-logrecord) will
set `ObservedTimestamp` to the current time when unset.)
* If provided by the user, the `Context` MUST be used to set
the [Context](./bridge-api.md#emit-a-logrecord). If not provided, `Context`
MUST be set to the current Context.
* If provided by the user, the `SeverityNumber` MUST be used to set
the [Severity Number](./data-model.md#field-severitynumber) when emitting the
logRecord. If not provided, `SeverityNumber` MUST be set
to `SEVERITY_NUMBER_INFO=9`.
* The [Severity Text](./data-model.md#field-severitytext) MUST not be set.
* If provided by the user, the `Attributes` MUST be used to set
the [Attributes](./data-model.md#field-attributes). The user
provided `Attributes` MUST not take over the `event.name`
attribute previously discussed.

## Optional and required parameters

The operations defined include various parameters, some of which are marked
Expand Down
82 changes: 82 additions & 0 deletions specification/logs/event-sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Events SDK

**Status**: [Experimental](../document-status.md)

<details>
<summary>Table of Contents</summary>

<!-- Re-generate TOC with `markdown-toc --no-first-h1 -i` -->

<!-- toc -->

- [Overview](#overview)
- [EventLoggerProvider](#eventloggerprovider)
- [EventLogger](#eventlogger)
* [Emit Event](#emit-event)
- [Additional Interfaces](#additional-interfaces)

<!-- tocstop -->

</details>

Users of OpenTelemetry need a way for instrumentation interactions with the
OpenTelemetry API to actually produce telemetry. The OpenTelemetry SDK
(henceforth referred to as the SDK) is an implementation of the OpenTelemetry
API that provides users with this functionally.

All implementations of the OpenTelemetry API MUST provide an SDK.

## Overview

From OpenTelemetry's perspective LogRecords and Events are both represented
using the same [data model](./event-api.md#data-model). Therefore, the default
implementation of an Event SDK MUST generate events using the [Logs Data Model](./data-model.md).

The SDK MAY be implemented on top of the [Logs Bridge API](./bridge-api.md).

## EventLoggerProvider

TODO

## EventLogger

TODO

### Emit Event

Emit a `LogRecord` representing an `Event`.

**Implementation Requirements:**

The implementation MUST use the parameters
to [emit a logRecord](./bridge-api.md#emit-a-logrecord) as follows:

* The `Name` MUST be used to set
the `event.name` [Attribute](./data-model.md#field-attributes). If
the `Attributes` provided by the user contain an `event.name` attribute the
value provided in the `Name` takes precedence.
* If provided by the user, the `Payload` MUST be used to set
the [Body](./data-model.md#field-body). If not provided, `Body` MUST not be
set.
* If provided by the user, the `Timestamp` MUST be used to set
the [Timestamp](./data-model.md#field-timestamp). If not provided, `Timestamp`
MUST be set to the current time when [emit](#emit-event) was called.
* The [Observed Timestamp](./data-model.md#field-observedtimestamp) MUST not be
set. (NOTE: [emit a logRecord](./bridge-api.md#emit-a-logrecord) will
set `ObservedTimestamp` to the current time when unset.)
* If provided by the user, the `Context` MUST be used to set
the [Context](./bridge-api.md#emit-a-logrecord). If not provided, `Context`
MUST be set to the current Context.
* If provided by the user, the `SeverityNumber` MUST be used to set
the [Severity Number](./data-model.md#field-severitynumber) when emitting the
logRecord. If not provided, `SeverityNumber` MUST be set
to `SEVERITY_NUMBER_INFO=9`.
* The [Severity Text](./data-model.md#field-severitytext) MUST not be set.
* If provided by the user, the `Attributes` MUST be used to set
the [Attributes](./data-model.md#field-attributes). The user
provided `Attributes` MUST not take over the `event.name`
attribute previously discussed.

## Additional Interfaces

TODO

0 comments on commit 5bd099a

Please sign in to comment.