CloudEvents should re-use existing HTTP or messaging conventions (#1182)

This commit is contained in:
Joao Grassi 2024-07-16 09:13:08 +02:00 committed by GitHub
parent c7fe07e542
commit 02ecf0c71e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 161 deletions

View File

@ -0,0 +1,5 @@
change_type: 'enhancement'
component: cloudevents
note: CloudEvents conventions to follow HTTP/Messaging Span conventions
issues: [654]
subtext:

View File

@ -11,12 +11,8 @@ linkTitle: CloudEvents Spans
<!-- toc --> <!-- toc -->
- [Definitions](#definitions) - [Definitions](#definitions)
- [Overview](#overview)
- [Conventions](#conventions) - [Conventions](#conventions)
- [Spans](#spans) - [Span attributes](#span-attributes)
- [Creation](#creation)
- [Processing](#processing)
- [Attributes](#attributes)
<!-- tocstop --> <!-- tocstop -->
@ -35,168 +31,20 @@ consult the
[CloudEvents Primer](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/primer.md) [CloudEvents Primer](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/primer.md)
document. document.
## Overview
A CloudEvent can be sent directly from producer to consumer.
For such a scenario, the traditional parent-child trace model works well.
However, CloudEvents are also used in distributed systems where an event
can go through many [hops](https://en.wikipedia.org/wiki/Hop_%28networking%29)
until it reaches a consumer. In this scenario, the traditional parent-child
trace model is not sufficient to produce a meaningful trace.
Consider the following scenario:
```
+----------+ +--------------+
| Producer | ---------------> | Intermediary |
+----------+ +--------------+
|
|
|
v
+----------+ +----------+
| Consumer | <----------------- | Queue |
+----------+ +----------+
```
With the traditional parent-child trace model, the above scenario would produce
two traces, completely independent from each other because the consumer
starts receiving (and thus has to specify a parent span) before it receives the event.
It is not possible to correlate a producer with a consumer(s) solely via a parent-child relationship.
```
+-------------------------------------------------+
| Trace 1 |
| |
| +---------------------------------------+ |
| | Send (auto-instr) | |
| +---------------------------------------+ |
| +------------------------------------+ |
| | Intermediary: Received (auto-instr)| |
| +------------------------------------+ |
| +------------------------------------+ |
| | Intermediary: Send (auto-instr) | |
| +------------------------------------+ |
| |
| Trace 2 |
| |
| +---------------------------------------+ |
| | Consumer: Receive (auto-instr) | |
| +---------------------------------------+ |
| |
+-------------------------------------------------+
```
This document defines semantic conventions to model the different stages
a CloudEvent can go through in a system, making it possible to create traces
that are meaningful and consistent. It covers creation, processing,
context propagation between producer and consumer(s) and attributes
to be added to spans.
With the proposed model, it is possible to have an overview of everything
that happened as the result of an event. One can, for example, answer the
following questions:
- What components in a system reacted to an event
- What further events were sent due to an incoming event
- Which event caused the exception
With the conventions in this document, the application scenario above would
produce a trace where it is possible to correlate a producer with a consumer(s):
```
+-------------------------------------------------------+
| Trace 1 |
| |
| +---------------------------------------+ |
| +---> | Create event | |
| | +---------------------------------------+ |
| | +---------------------------------------+ |
| | | Send (auto-instr) | |
| | +---------------------------------------+ |
| | +------------------------------------+ |
| | | Intermediary: Received (auto-instr)| |
| | +------------------------------------+ |
| | +------------------------------------+ |
| | | Intermediary: Send (auto-instr) | |
| |Link +------------------------------------+ |
| | |
| | |
| | |
| | Trace 2 |
| | |
| | +---------------------------------------+ |
| | | Consumer: Receive (auto-instr) | |
| | +---------------------------------------+ |
| | +-------------------------------------+ |
| +------ | Consumer: Process | |
| +-------------------------------------+ |
| |
+-------------------------------------------------------+
```
## Conventions ## Conventions
To achieve the trace above, it is necessary to capture the context of CloudEvent-specific instrumentations SHOULD follow the span structure described in
the event creation so that when the CloudEvent reaches its destination(s), this the [Semantic Conventions for Messaging Spans](../messaging/messaging-spans.md).
context can be continued. Each CloudEvent acts then as the medium of this
context propagation.
This document relies on the CloudEvents specification, which defines this If CloudEvents are instrumented independently of the above conventions,
context propagation mechanism via the instrumentations can rely on the
[CloudEvents Distributed Tracing Extension](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/extensions/distributed-tracing.md).
Once the trace context is set on the event
via the Distributed Tracing Extension, it MUST not be modified.
The remainder of this section describes the semantic conventions for Spans
required to achieve the proposed trace.
### Spans
#### Creation
Instrumentation SHOULD create a new span and populate the
[CloudEvents Distributed Tracing Extension](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/extensions/distributed-tracing.md) [CloudEvents Distributed Tracing Extension](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/extensions/distributed-tracing.md)
on the event. This applies when: as means to propagate the trace context.
- A CloudEvent is created by the instrumented library. ## Span attributes
It may be impossible or impractical to create the Span during event
creation (e.g. inside the constructor or in a factory method),
so instrumentation MAY create the Span later, when passing the event to the transport layer.
- A CloudEvent is created outside of the instrumented library
(e.g. directly constructed by the application owner, without calling a constructor or factory method),
and passed without the Distributed Tracing Extension populated.
In case a CloudEvent is passed to the instrumented library with the Additionally, instrumentations may record the following CloudEvent-specific
Distributed Tracing Extension already populated, instrumentation MUST NOT create attributes on spans created from the conventions described above.
a span and MUST NOT modify the Distributed Tracing Extension on the event.
- Span name: `CloudEvents Create <event_type>`
- Span kind: PRODUCER
- Span attributes: Instrumentation MUST add the required attributes defined
in the [table below](#attributes).
#### Processing
When an instrumented library supports processing of a single CloudEvent,
instrumentation SHOULD create a new span to trace it.
Instrumentation SHOULD set the remote trace context from the
Distributed Tracing Extension as a link on the processing span.
Instrumentation MAY add attributes to the link to further describe it.
- Span name: `CloudEvents Process <event_type>`
- Span kind: CONSUMER
- Span attributes: Instrumentation MUST add the required attributes defined
in the [table below](#attributes).
### Attributes
The following attributes are applicable to creation and processing Spans.
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->
<!-- semconv cloudevents --> <!-- semconv cloudevents -->