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

Add OpenTracing compatibility section. #1101

Merged
Merged
Changes from 30 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
1c9bc9d
Initial OpenTracing compatibility section.
carlosalberto Aug 10, 2020
bcdfb00
Fixes.
carlosalberto Aug 10, 2020
3195643
Fix typo.
carlosalberto Aug 10, 2020
92da36f
Apply feedback.
carlosalberto Aug 12, 2020
dd331ab
Fix typo.
carlosalberto Aug 12, 2020
b944a2c
Have the OT doc under a compatibility subdir.
carlosalberto Aug 14, 2020
c6027ba
Apply feedback.
carlosalberto Aug 17, 2020
272198e
Remove the read-only restriction for SpanContext values.
carlosalberto Aug 17, 2020
bf66d04
Update this PR.
carlosalberto Oct 14, 2020
36043f6
Do an improvement pass.
carlosalberto Oct 15, 2020
57ed80a
Merge branch 'master' into add_ot_compatibility_new
carlosalberto Oct 15, 2020
d1ce668
Update the toplevel organization.
carlosalberto Oct 15, 2020
88fa597
Clarify returned values.
carlosalberto Oct 15, 2020
5c8bc99
Add a note on intention.
carlosalberto Oct 15, 2020
7ded0ce
Use Context as the container for Span/Baggage.
carlosalberto Oct 16, 2020
1567a97
Minor fixes.
carlosalberto Oct 16, 2020
155a286
Update specification/compatibility/opentracing.md
carlosalberto Dec 10, 2020
d92c209
Mention semantic conventions mapping.
carlosalberto Dec 10, 2020
597fff7
Merge branch 'master' into add_ot_compatibility_new
carlosalberto Dec 11, 2020
e5deff1
Fix typo.
carlosalberto Dec 11, 2020
bb173ca
Improve the doc & clarify things.
carlosalberto Dec 11, 2020
a6fd708
BaggageManager is not needed anymore.
carlosalberto Dec 11, 2020
10d4ac4
Merge branch 'master' into add_ot_compatibility_new
carlosalberto Dec 14, 2020
69d1424
More feedback.
carlosalberto Dec 16, 2020
1920d88
Merge branch 'master' into add_ot_compatibility_new
carlosalberto Dec 16, 2020
b569ee9
Merge branch 'master' into add_ot_compatibility_new
yurishkuro Dec 27, 2020
0dff253
Merge branch 'master' into add_ot_compatibility_new
carlosalberto Jan 6, 2021
439f484
Update specification/compatibility/opentracing.md
carlosalberto Jan 23, 2021
c18c10b
Update specification/compatibility/opentracing.md
carlosalberto Jan 23, 2021
ab02876
Merge branch 'master' into add_ot_compatibility_new
carlosalberto Jan 23, 2021
40b396c
Merge branch 'main' into add_ot_compatibility_new
carlosalberto Mar 4, 2021
d65fcdc
Merge branch 'main' into add_ot_compatibility_new
carlosalberto Mar 5, 2021
42a55e7
Add status.
carlosalberto Mar 5, 2021
c783567
Initial pass of feedback applied.
carlosalberto Mar 7, 2021
8547dc4
Automatically store Span Shim in the Context.
carlosalberto Mar 7, 2021
1fb02e6
Address Reiley's feedback.
carlosalberto Mar 7, 2021
350310f
Specify custom propagators to handle TextMap/HTTPHeaders.
carlosalberto Mar 7, 2021
1e842c7
Mention that Inject/Extract MAY indeed raise errors.
carlosalberto Mar 8, 2021
2a8dd16
Simplify the Span/SpanContext relationship explanation.
carlosalberto Mar 8, 2021
cfcb3d5
Clarify the Propagators used for Inject/Extract().
carlosalberto Mar 9, 2021
8c2d494
Fix links.
carlosalberto Mar 9, 2021
3c5f040
Merge branch 'main' into add_ot_compatibility_new
SergeyKanzhelev Mar 9, 2021
b1296a7
Merge branch 'main' into add_ot_compatibility_new
carlosalberto Mar 16, 2021
c340224
Merge branch 'main' into add_ot_compatibility_new
carlosalberto Mar 17, 2021
c2281fc
Update CHANGELOG.
carlosalberto Mar 17, 2021
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
268 changes: 268 additions & 0 deletions specification/compatibility/opentracing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
# OpenTracing Compatibility

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

carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
* [Abstract](#abstract)
* [Create an OpenTracing Tracer Shim](#create-an-opentracing-tracer-shim)
* [Tracer Shim](#tracer-shim)
* [Inject](#inject)
* [Extract](#extract)
* [Span Shim](#span-shim)
* [OpenTelemetry Span and SpanContext relationship](#opentelemetry-span-and-spancontext-relationship)
* [Get Context](#get-context)
* [Get Baggage Item](#get-baggage-item)
* [Set Baggage Item](#set-baggage-item)
* [Set Tag](#set-tag)
* [Log](#log)
* [Finish](#finish)
* [SpanContext Shim](#spancontext-shim)
* [Get Baggage Items](#get-baggage-items)
* [ScopeManager Shim](#scopemanager-shim)
* [Activate a Span](#activate-a-span)
* [Get the active Span](#get-the-active-span)
* [Semantic conventions mapping](#semantic-conventions-mapping)

</details>

## Abstract

The OpenTelemetry project aims to provide backwards compatibility with the
[OpenTracing](https://opentracing.io) project in order to ease migration of
instrumented codebases.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

This functionality will be provided as a bridge layer implementing the
[OpenTracing API](https://github.com/opentracing/specification) using the
OpenTelemetry API. This layer MUST NOT rely on implementation specific details
of any SDK.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

More specifically, the intention is to allow OpenTracing instrumentation to be
recorded using OpenTelemetry. This Shim Layer MUST NOT publicly expose any
upstream OpenTelemetry API.

This functionality MUST be defined in its own OpenTracing Shim Layer, not in the
OpenTracing nor the OpenTelemetry API or SDK.

The OpenTracing Shim and the OpenTelemetry API/SDK are expected to be consumed
simultaneously in a running service, in order to ease migration from the former
to the latter.

## Create an OpenTracing Tracer Shim

This operation is used to create a new OpenTracing `Tracer`:

This operation MUST accept the following parameters:

- An OpenTelemetry `Tracer`, used to create `Span`s.
- A set of OpenTelemetry `Propagator`s of the supported types, used to perform
context injection and extraction. Usually these are the global
`Composite Propagator`s.

The API MUST return an OpenTracing `Tracer`.

## Tracer Shim

### Inject

Parameters:

- A `SpanContext`.
- A `Format` descriptor.
- A carrier.

Inject the underlying OpenTelemetry `Span` and `Bagagge` using the registered
OpenTelemetry `Propagator`s:

- `TEXT_MAP` and `HTTP_HEADERS` formats MUST use the registered OpenTelemetry
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
`HTTPTextPropagator`, if any.

Errors MUST NOT be raised if the specified `Format` is `BINARY`.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

### Extract

Parameters:

- A `Format` descriptor.
- A carrier.

Extract OpenTelemetry `Span` and `Baggage` from a carrier using the registered
OpenTelemetry `Propagator`s:

- `TEXT_MAP` and `HTTP_HEADERS` formats MUST use the registered OpenTelemetry
`HTTPTextPropagator`, if any.

Returns a `SpanContext` Shim with the underlying extracted OpenTelemetry
`Span` and `Baggage`, or null if either the `Format` is `BINARY` or
no value could be extracted.

## Span Shim

The OpenTracing `Span` operations MUST be implemented using underlying OpenTelemetry `Span`
and `Baggage` values through a `SpanContext` Shim.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

In order to satisfy the OpenTracing `Span` requirements:
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

- The associated `SpanContext` Shim object will contain an OpenTelemetry `SpanContext`
and a `Baggage`. The `SpanContext` Shim MUST be immutable and MUST be
replaced every time baggage is updated through [Set Baggage Item](#set-baggage-item).
- An underlying OpenTelemetry `Span` MUST be associated with only one
`SpanContext` Shim at a time. This is done in order to keep its linked `Baggage`
consistent across all execution units at all times.

This is a simple graphical representation of the mentioned objects:

```
Span Shim
+- OpenTelemetry Span
+- SpanContext Shim
+- OpenTelemetry SpanContext
+- OpenTelemetry Baggage
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
```

The OpenTelemetry `Span` in `Span` Shim is also used to get and set
its currently associated `SpanContext` Shim. See
[OpenTelemetry Span and SpanContext relationship](#opentelemetry-span-and-spancontext-relationship).

The `Log` operations MUST be implemented using the OpenTelemetry
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
`Span`'s `Add Events` operations.

The `Set Tag` operations MUST be implemented using the OpenTelemetry
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
`Span`'s `Set Attributes` operations.

### OpenTelemetry Span and SpanContext relationship

A given OpenTelemetry `Span` MUST be associated with only one
`SpanContext` Shim at all times for all execution units, in order
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
to keep any linked `Baggage` consistent across all execution
units at all times.

An example of this scenario is having an OpenTracing `Span` have its
[Set Baggage Item](#set-baggage-item) operation called from two different
execution units (e.g. threads), and afterwards have its [Context](#get-context)
fetched in order to [iterate over its baggage values](#get-baggage-items).

Getting and setting the currently associated `SpanContext` for a specified
OpenTelemetry `Span` MUST be safe to call from different execution units.

Managing this relationship is an implementation detail. It can be implemented,
for example, with the help of a global synchronized dictionary, or with an
additional attribute in OpenTelemetry `Span` objects for dynamic languages.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am trying to understand the purpose of these paragraphs. Are they trying to describe a difference in behavior between OT and OTEL baggage? Specifically, in OT the span.setBaggage operation is change-in-place and affects what baggage can be seen by different threads (and, therefore, has an inherent race condition, due to OT design). In contrast, OTEL stores baggage in the Context and removes this race condition by design, but it is not clear to be how the shim deals with it since the Context is never mentioned. If we carry the Baggage object directly in the SpanContext shim, then it can reproduce the same OT behavior.

Copy link
Contributor Author

@carlosalberto carlosalberto Jan 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Java and C# Baggage exists in its own object, which basically means we can leave Context entirely out (at least for those languages).

Specifically, in OT the span.setBaggage operation is change-in-place and affects what baggage can be seen by different threads

This is indeed the reason I'm mentioning here the details. However, I'm also trying to keep the invariant of an actual SpanContext being entirely replaced:

// OT perspective
SpanContext ctx1 = span.getContext();
span.setBaggageItem("hey", "you");
assertNotEquals(ctx1, span.getContext());

If you think this invariant is not worth keeping (and it's enough to simply keep the actual values consistent), I can try to play around and simplify things.


### Get Context

Returns the [associated](#opentelemetry-span-and-spancontext-relationship)
`SpanContext` Shim.

### Get Baggage Item

Parameters:

- The baggage key, a string.

Returns a value for the specified key in the OpenTelemetry `Baggage` of the
associated `SpanContext` Shim or null if none exists.

This is accomplished by getting the
[associated](#opentelemetry-span-and-spancontext-relationship)
`SpanContext` Shim and do a lookup for the specified key in the OpenTelemetry
`Baggage` instance.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

### Set Baggage Item

Parameters:

- The baggage key, a string.
- The baggage value, a string.

Creates a new `SpanContext` Shim with a new OpenTelemetry `Baggage` containing
the specified `Baggage` key/value pair. The resulting `SpanContext` Shim is then
[associated](#opentelemetry-span-and-spancontext-relationship) to the underlying
OpenTelemetry `Span`.

carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
### Set Tag

Parameters:

- The tag key, a string.
- The tag value, which must be either a string, a boolean value, or a numeric type.

Calls `Set Attribute` on the underlying OpenTelemetry `Span` with the specified
key/value pair.

The value MUST be [mapped](#semantic-conventions-mapping) to the respective
OpenTelemetry `Attribute`, or converted to a string if the value type is not supported.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

If the type of the specified value is not supported, the value MUST be converted
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
to a string.

### Log

Parameters:

- A set of key/value pairs, where keys must be strings, and the values may have
any type.

Calls `Add Event` on the underlying OpenTelemetry `Span` with the specified
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
key/value pair set.

The `Add Event`'s `name` parameter MUST be the value with the `event` key in
the pair set, or else fallback to use the `log` literal string.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

The set of values MUST be [mapped](#semantic-conventions-mapping) to the respective
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
OpenTelemetry `Attribute`, or converted to a string if the value type is not supported.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

If an explicit timestamp is specified, a conversion MUST be done to match the
OpenTracing and OpenTelemetry units.

### Finish

Calls `End` on the underlying OpenTelemetry `Span`.

If an explicit timestamp is specified, a conversion MUST be done to match the
OpenTracing and OpenTelemetry units.

### SpanContext Shim
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

The `SpanContext` Shim MUST contain the associated `Span` and `Baggage` values.

This object MUST be immutable.

#### Get Baggage Items

Returns a dictionary, collection, or iterator (depending on the requirements of the OpenTracing API for a specific language)
backed by the associated OpenTelemetry `Baggage` values.

## ScopeManager Shim

For OpenTracing languages implementing the `ScopeManager` interface, its operations
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
MUST be implemented using the OpenTelemetry Context Propagation API in order
to get and set active `Context` instances.

### Activate a Span

Parameters:

- A `Span`.

Gets the [associated](#opentelemetry-span-and-spancontext-relationship)
`SpanContext` Shim for the specified `Span` and puts its OpenTelemetry
`SpanContext` and `Bagagge` in a new `Context`, which is then set as the
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved
currently active instance.

### Get the active Span

Gets the active OpenTelemetry `Span` and returns a `Span` Shim wrapping it.
carlosalberto marked this conversation as resolved.
Show resolved Hide resolved

The API MUST return null if none exist.

## Semantic Conventions Mapping

The OpenTracing Shim MUST map certain elements when calling the underlying
OpenTelemetry API.

[OpenTracing Span Tags](https://github.com/opentracing/specification/blob/master/semantic_conventions.md#standard-span-tags-and-log-fields):

- `error` maps to [StatusCode](../trace/api.md##set-status):
- `true` maps to `Error`.
- `false` maps to `Ok`.
- no value being set maps to `Unset`.