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

Generalize span operations #209

Merged
merged 13 commits into from
Aug 17, 2019
2 changes: 1 addition & 1 deletion specification/api-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

- [Meter](#meter)
Expand Down
2 changes: 1 addition & 1 deletion specification/api-propagators.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

- [Binary Format](#binary-format)
Expand Down
153 changes: 59 additions & 94 deletions specification/api-tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

* [Data types](#data-types)
Expand Down Expand Up @@ -82,110 +82,84 @@ A duration is the elapsed time between two events.

## Tracer

### Obtaining a tracer

A tracer SHOULD be obtained from a global registry, for example
`OpenTelemetry.getTracer()`.

The registration to the registry depends on the language. In some languages the
tracer is explicitly created and registered from user code and other languages
the tracer implementation is resolved from linked dependencies using provider
pattern.

The tracer object construction depends on the implementation. Various
implementations might require to specify different configuration properties at
creation time. In languages where provider pattern is used the configuration is
provided externally.

#### Tracer provider

Tracer provider is an internal class used by the global registry
(`OpenTelemetry`) to get a tracer instance. The global registry delegates calls
to the provider every time a tracer instance is requested. This is necessary
for use-cases when a single instrumentation code runs for multiple deployments.

The tracer provider is registered to API usually via language-specific
mechanism, for instance `ServiceLoader` in Java.

##### Runtime with multiple deployments/applications

Application runtimes which support multiple deployments/applications might need
to provide a different tracer instance to each deployment. In this case the
runtime provides its own implementation of provider which returns a different
tracer for each deployment.

### Tracer operations

#### GetCurrentSpan

Returns the current Span from the current context.

There should be no parameter.

Returns the default `Span` that does nothing and has an invalid `SpanContext` if
no `Span` is associated with the current context, otherwise the current `Span`
from the context.

#### WithSpan
Enters the scope of code where the given `Span` is in the current context.
The OpenTelemetry library achieves in-process context propagation of `Span`s by
way of the `Tracer`.

Required parameters:

- The `Span` to be set to the current context.

Returns an object that defines a scope where the given `Span` will be set to the
current context.
The `Tracer` is responsible for tracking the currently active `Span`, and
exposes methods for creating and activating new `Span`s. The `Tracer` is
configured with `Propagator`s which support transferring span context across
process boundaries.

The scope is exited and previous state should be restored when the returned
object is closed.
`Tracer`s are generally expected to be used as singletons. Implementations
SHOULD provide a single global default `Tracer`.

#### SpanBuilder
Returns a `SpanBuilder` to create and start a new `Span` if a `Builder` pattern
for [Span creation](#span-creation) is used.

Required parameters:
Some applications may require multiple `Tracer` instances, e.g. to create
`Span`s on behalf of other applications. Implementations MAY provide a global
registry of `Tracer`s for such applications.

- Name of the span.

Returns a `SpanBuilder` to create and start a new `Span`.

#### RecordSpanData
### Obtaining a tracer

Records a `SpanData`.
`Tracer` object construction and registration will vary by implementation.
`Tracer`s may be explicitly created and registered from user code, or resolved
from linked dependencies using the provider pattern.

Required parameters:
Implementations might require the user to specify configuration properties at
`Tracer` creation time, or rely on external configuration, e.g. when using the
provider pattern.

- `SpanData` to be reported to all exporters.
##### Runtimes with multiple deployments/applications

This API allows to send a pre-populated span object to the exporter. Sampling
and recording decisions as well as other collection optimizations are a
responsibility of a caller.
Runtimes that support multiple deployments or applications might need to
provide a different `Tracer` instance to each deployment. To support this,

Note, the `SpanContext` object in the span population with the values that will
allow correlation of telemetry is also a caller responsibility.
the global `Tracer` registry may delegate calls to create new `Tracer`s to a
separate `Provider` component, and the runtime may include its own `Provider`
implementation which returns a different `Tracer` for each deployment.

This API should be non-blocking.
`Provider`s are registered with the API via some language-specific mechanism,
for instance the `ServiceLoader` class in Java.

#### GetBinaryFormat
Returns the binary format interface which can serialize/deserialize `Span`s.
### Tracer operations

There should be no parameter.
The `Tracer` MUST provide methods to:

Returns the binary format for this implementation. If no implementation is
provided then no-op implementation will be used.
- Get the currently active `Span`
- Create a new `Span`
- Make a given `Span` as active

#### GetHttpTextFormat
Returns the HTTP text format interface which can inject/extract `Span`s.
The `Tracer` SHOULD allow end users to configure other tracing components that
control how `Span`s are passed across process boundaries, inclucding the binary
and text format `Propagator`s used to serialize `Span`s created by the
`Tracer`.

There should be no parameter.
When getting the current span, the `Tracer` MUST return a placeholder `Span`
with an invalid `SpanContext` if there is no currently active `Span`.

Returns the HTTP text format for this implementation. If no implementation is
provided then no-op implementation will be used.
When creating a new `Span`, the `Tracer` MUST allow the caller to specify the
new `Span`'s parent in the form of a `Span` or `SpanContext`. The `Tracer`
SHOULD create each new `Span` as a child of its active `Span` unless an
explicit parent is provided or the option to create a span without a parent is
selected, or the current active `Span` is invalid.

Usually this will be the W3C Trace Context as the HTTP text format. For more
The `Tracer` MUST provide a way to update its active `Span`, and MAY provide
convenience methods to manage a `Span`'s lifetime and the scope in which a
`Span` is active. When an active `Span` is made inactive, the previously-active
`Span` SHOULD be made active. A `Span` maybe finished (i.e. have a non-null end
time) but stil active. A `Span` may be active on one thread after it has been
made inactive on another.

The `Tracer` MUST support recording `Span`s that were created _out of band_,
i.e. not by the tracer itself. For this reason, implementations MUST NOT
require that a `Span`'s start and end timestamps match the wall time when it is
created, made active, or finished.

The implementation MUST provide no-op binary and text `Propagator`s, which the
`Tracer` SHOULD use by default if other propagators are not configured. SDKs
SHOULD use the W3C HTTP Trace Context as the default text format. For more
details, see [trace-context](https://github.com/w3c/trace-context).

## SpanContext

A `SpanContext` represents the portion of a `Span` which must be serialized and
propagated along side of a distributed context. `SpanContext`s are immutable.
`SpanContext` MUST be a final (sealed) class.
Expand Down Expand Up @@ -268,15 +242,6 @@ empty by default:
- `Link`s
- `Event`s

The `Tracer` MUST allow the caller to specify the new `Span`'s parent in the
form of a `Span` or `SpanContext`. The `Tracer` SHOULD create each new `Span` as
a child of its active `Span` unless an explicit parent is provided or the
option to create a span without a parent is selected.```

The `Tracer` MUST provide a way to update its active `Span`, and MAY provide
convenience methods to manage a `Span`'s lifetime of and the scope in which a
`Span` is active.

Each span has zero or one parent span and zero or more child spans, which
represent causally related operations. A tree of related spans comprises a
trace. A span is said to be a _root span_ if it does not have a parent. Each
Expand Down