From fecfb7dfc2fd228528bc433ae13e073e3f8c5161 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:10:57 -0600 Subject: [PATCH] Define Event API arguments and mapping to log record (#3772) In the 11/17/23 Event SIG we discussed and reached agreement on a number of things related to the Event API and how its parameters should manifest on resulting log record: - Some, but not all the parameters of [emit a logRecord](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md#emit-a-logrecord) should be exposed in the Event API - [LogRecord#SeverityText](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitytext) should not be exposed as an Event API parameter. The SeverityText is used to record the original severity as recorded in the original log framework. The Event API is not for bridging log frameworks and this this field does not make sense to expose. The Event API implementation should leave SeverityText blank. - [LogRecord#ObservedTimestamp](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-observedtimestamp) should not be as exposed as an Event API parameter. The semantics of ObservedTimestamp are defined as "Time when the event was observed by the collection system". For the Event API, the ObserveTimestamp is always when the Event is emitted. - The Event Payload, which conforms to the well defined schema for a particular `event.name` (event.domain is going away in #3749) should be an [AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/ea449ae0e9b282f96ec12a09e796dbb3d390ed4f/opentelemetry/proto/common/v1/common.proto#L28) and recorded to the log record body. - We need some way to sample / filter Events based on the notion of priority / severity. We decided to use the [LogRecord#SeverityNumber](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber) field for this purpose rather than introducing a new concept. LogRecord#SeverityNumber is optional, and we want the equivalent Event API parameter to be optional as well. Therefore, I've indicated that Event API implementations should set a default SeverityNumber of 10. Without choosing a default, future sampling strategies that are based on SeverityNumber will filter away all Events which do not explicitly set a SeverityNumber, which is not desirable. Note that there is going to be a corresponding PR in `semantic-conventions` which says that Events put their payload in the LogRecord#Body field. --------- Co-authored-by: Carlos Alberto Cortez Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CHANGELOG.md | 4 ++ specification/logs/event-api.md | 67 ++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4e37d86b02..e369eea4e90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ release. ([#3741](https://github.com/open-telemetry/opentelemetry-specification/pull/3741)) - BREAKING: Change `event.name` definition to include `namespace` and removed `event.domain` from log event attributes. ([#3749](https://github.com/open-telemetry/opentelemetry-specification/pull/3749)) +- BREAKING: Refine the arguments of the emit Event API. Instead of accepting + a `LogRecord`, the individual arguments are enumerated along with the + implementation requirements on how those arguments map to `LogRecord`. + ([#3772](https://github.com/open-telemetry/opentelemetry-specification/pull/3772)) ### Resource diff --git a/specification/logs/event-api.md b/specification/logs/event-api.md index c543e70c035..89ed5adc31f 100644 --- a/specification/logs/event-api.md +++ b/specification/logs/event-api.md @@ -14,6 +14,7 @@ * [EventLogger Operations](#eventlogger-operations) + [Create EventLogger](#create-eventlogger) + [Emit Event](#emit-event) +- [Optional and required parameters](#optional-and-required-parameters) @@ -32,9 +33,9 @@ using the same [data model](./data-model.md). However, OpenTelemetry does recognize a subtle semantic difference between LogRecords and Events: Events are LogRecords which have a `name` which uniquely defines a particular class or type of event. All events with the same `name` -follow 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). +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 @@ -74,17 +75,55 @@ This function MAY be named `logEvent`. **Parameters:** -* `event_name` - the Event name. This argument MUST be recorded as a `LogRecord` - 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](./data-model.md#log-and-event-record-definition) representing - the Event. +* The `Name` of the Event, as described + in [event.name semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/events.md). +* The (`AnyValue`) (optional) `Payload` of the Event. +* The `Timestamp` (optional) of the Event. +* The [Context](../context/README.md) (optional) associated with the Event. +* The `SeverityNumber` (optional) of the Event. +* The `Attributes` (optional) of the Event. Event `Attributes` provide + additional details about the Event which are not part of the + well-defined `Payload`. **Implementation Requirements:** -The implementation MUST [emit](./bridge-api.md#emit-a-logrecord) the `logRecord` to -the `logger` specified when [creating the EventLogger](#create-eventlogger) -after making the following changes: - -* The `event_name` MUST be set as the `event.name` attribute on the `logRecord`. +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.domain` and `event.name` + attributes previously discussed. + +## Optional and required parameters + +The operations defined include various parameters, some of which are marked +optional. Parameters not marked optional are required. + +For each optional parameter, the API MUST be structured to accept it, but MUST +NOT obligate a user to provide it. + +For each required parameter, the API MUST be structured to obligate a user to +provide it.