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

Propose "Named Tracers" #16

Merged
merged 34 commits into from
Sep 26, 2019
Merged
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
67f199a
First draft: "named tracers"
z1c0 Aug 8, 2019
5c6c2b6
Implement feedback.
z1c0 Aug 8, 2019
dd23e27
Merge pull request #1 from z1c0/master
z1c0 Aug 12, 2019
c68f45d
Merge remote-tracking branch 'upstream/master'
z1c0 Aug 12, 2019
92104bd
Move named tracers proposal into text folder
z1c0 Aug 12, 2019
93ff941
Merge pull request #2 from z1c0/master
z1c0 Aug 12, 2019
5f7f2a0
Apply suggestions from code review
z1c0 Aug 13, 2019
f628980
Apply suggestions from code review
z1c0 Aug 13, 2019
0a676a5
Add examples section.
z1c0 Aug 13, 2019
3c4d150
Update 0000-named-tracers.md
z1c0 Aug 13, 2019
17de20c
Merge pull request #4 from dynatrace-oss-contrib/z1c0-patch-2
z1c0 Aug 14, 2019
40d93e3
Merge branch 'master' into master
z1c0 Aug 14, 2019
94c4b9c
Merge branch 'master' into master
bogdandrutu Aug 27, 2019
eba8220
Implement feedback from code review
z1c0 Aug 28, 2019
6192c93
Merge branch 'master' of https://github.com/open-telemetry/oteps
Oberon00 Aug 30, 2019
368f6fd
Remove the implementation details about enabling / disabling ... of
z1c0 Sep 16, 2019
8219749
Merge branch 'master' into master
z1c0 Sep 16, 2019
890fd79
Update text/0000-named-tracers.md
z1c0 Sep 17, 2019
c905402
Update text/0000-named-tracers.md
z1c0 Sep 17, 2019
db2f617
Reworked this RFC based on feedback on GitHub.
z1c0 Sep 19, 2019
a8f344f
Merge branch 'master' into master
z1c0 Sep 19, 2019
c747703
Implement latest review suggestions
z1c0 Sep 20, 2019
22df407
Merge branch 'master' of https://github.com/dynatrace-oss-contrib/rfcs
z1c0 Sep 20, 2019
cfde119
Removed formatting
z1c0 Sep 22, 2019
f83fb87
Re-introduce plain string factory and move Resource-based approach to…
z1c0 Sep 24, 2019
f569a2a
Merge branch 'master' into master
z1c0 Sep 24, 2019
8a882f2
Use ` to format the names in the examples.
bogdandrutu Sep 24, 2019
617f5f8
Fix typo and broken link
z1c0 Sep 25, 2019
fe68315
Merge branch 'master' of https://github.com/dynatrace-oss-contrib/rfcs
z1c0 Sep 25, 2019
005cfa2
Extended the OTEP to included Metrics as well.
z1c0 Sep 26, 2019
124bc83
Update text/0000-named-tracers.md
z1c0 Sep 26, 2019
f618455
Update text/0000-named-tracers.md
z1c0 Sep 26, 2019
595f19d
Implement latest feedback.
z1c0 Sep 26, 2019
995819d
Rename 0000-named-tracers.md to 0016-named-tracers.md
bogdandrutu Sep 26, 2019
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
107 changes: 107 additions & 0 deletions text/0000-named-tracers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Named Tracers and Meters

z1c0 marked this conversation as resolved.
Show resolved Hide resolved
**Status:** `proposed`

_Creating Tracers and Meters using a factory mechanism and naming those Tracers / Meters in accordance with the library that provides the instrumentation for those components._

## Suggested reading

* [Proposal: Tracer Components](https://github.com/open-telemetry/opentelemetry-specification/issues/10)
* [Global Instance discussions](https://github.com/open-telemetry/opentelemetry-specification/labels/global%20instance)
* [Proposal: Add a version resource](https://github.com/open-telemetry/oteps/pull/38)

## Motivation

The mechanism of "Named Tracers and Meters" proposed here is motivated by following scenarios:

* For a consumer of OpenTelemetry instrumentation libraries, there is currently no possibility of influencing the amount of the data produced by such libraries. Instrumentation libraries can easily "spam" backend systems, deliver bogus data or - in the worst case - crash or slow down applications. These problems might even occur suddenly in production environments caused by external factors such as increasing load or unexpected input data.
z1c0 marked this conversation as resolved.
Show resolved Hide resolved

* If a library hasn't implemented [semantic conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md) correctly or those conventions change over time, it's currently hard to interpret and sanitize these data selectively. The produced Spans or Metrics cannot be associated with those instrumentation libraries later.

This proposal attempts to solve the stated problems by introducing the concept of:
* _Named Tracers and Meters_ identified via a **name** (e.g. _"io.opentelemetry.contrib.mongodb"_) and a **version** (e.g._"semver:1.0.0"_) which is associated with the Tracer / Meter and the Spans / Metrics it produces.
* A `TracerFactory` / `MeterFactory` as the only means of creating a Tracer or Meter.

Based on such an identifier, a Sampler could be implemented that discards Spans or Metrics from certain libraries. Also, by providing custom Exporters, Span or Metric data could be sanitized before it gets processed in a back-end system. However, this is beyond the scope of this proposal, which only provides the fundamental mechanisms.

## Explanation

From a user perspective, working with *Named Tracers / Meters* and `TracerFactory` / `MeterFactory` is conceptually similar to how e.g. the [Java logging API](https://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#getLogger(java.lang.String)) and logging frameworks like [log4j](https://www.slf4j.org/apidocs/org/slf4j/LoggerFactory.html) work. In analogy to requesting Logger objects through LoggerFactories, a tracing library would create specific Tracer / Meter objects through a TracerFactory / MeterFactory.

z1c0 marked this conversation as resolved.
Show resolved Hide resolved
New Tracers or Meters can be created by providing the name and version of an instrumentation library. The version (following the convention proposed in https://github.com/open-telemetry/oteps/pull/38) is basically optional but *should* be supplied since only this information enables following scenarios:
* Only a specific range of versions of a given instrumentation library need to be suppressed, while other versions are allowed (e.g. due to a bug in those specific versions).
* Go modules allow multiple versions of the same middleware in a single build so those need to be determined at runtime.

```java
// Create a tracer/meter for a given instrumentation library in a specific version.
Tracer tracer = OpenTelemetry.getTracerFactory().getTracer("io.opentelemetry.contrib.mongodb", "semver:1.0.0");
Meter meter = OpenTelemetry.getMeterFactory().getMeter("io.opentelemetry.contrib.mongodb", "semver:1.0.0");
```

These factories (`TracerFactory` and `MeterFactory`) replace the global `Tracer` / `Meter` singleton objects as ubiquitous points to request Tracer and Meter instances.

The *name* used to create a Tracer or Meter must identify the *instrumentation* libraries (also referred to as *integrations*) and not the instrumented libraries. These instrumentation libraries could be libraries developed in an OpenTelemetry repository, a 3rd party implementation or even auto-injected code (see [Open Telemetry Without Manual Instrumentation OTEP](https://github.com/open-telemetry/oteps/blob/master/text/0001-telemetry-without-manual-instrumentation.md)). See also the examples for identifiers at the end.
If a library (or application) has instrumentation built-in, it is both the instrumenting and instrumented library and should pass its own name here. In all other cases (and to distinguish them from that case), the distinction between instrumenting and instrumented library is very important. For example, if an HTTP library `com.example.http` is instrumented by either `io.opentelemetry.contrib.examplehttp` or `com.example.company.examplehttpintegration`, then it is important that the Tracer is not named `com.example.http` but after the actual instrumentation library.

If no name (null or empty string) is specified, following the suggestions in ["error handling proposal"](https://github.com/open-telemetry/opentelemetry-specification/pull/153), a "smart default" will be applied and a default Tracer / Meter implementation is returned.

### Examples (of Tracer and Meter names)

Since Tracer and Meter names describe the libraries which use those Tracers and Meters, their names should be defined in a way that makes them as unique as possible.
The name of the Tracer / Meter should represent the identity of the library, class or package that provides the instrumentation.

Examples (based on existing contribution libraries from OpenTracing and OpenCensus):

* `io.opentracing.contrib.spring.rabbitmq`
* `io.opentracing.contrib.jdbc`
* `io.opentracing.thrift`
* `io.opentracing.contrib.asynchttpclient`
* `io.opencensus.contrib.http.servlet`
* `io.opencensus.contrib.spring.sleuth.v1x`
* `io.opencesus.contrib.http.jaxrs`
* `github.com/opentracing-contrib/go-amqp` (Go)
* `github.com/opentracing-contrib/go-grpc` (Go)
* `OpenTracing.Contrib.NetCore.AspNetCore` (.NET)
* `OpenTracing.Contrib.NetCore.EntityFrameworkCore` (.NET)

## Internal details

By providing a `TracerFactory` / `MeterFactory` and *Named Tracers / Meters*, a vendor or OpenTelemetry implementation gains more flexibility in providing Tracers and Meters and which attributes they set in the resulting Spans and Metrics that are produced.

On an SDK level, the SpanData class and its Metrics counterpart are extended with a `getLibraryResource` function that returns the resource associated with the Tracer / Meter that created it.

## Prior art and alternatives

This proposal originates from an `opentelemetry-specification` proposal on [components](https://github.com/open-telemetry/opentelemetry-specification/issues/10) since having a concept of named Tracers would automatically enable determining this semantic `component` property.

Alternatively, instead of having a `TracerFactory`, existing (global) Tracers could return additional indirection objects (called e.g. `TraceComponent`), which would be able to produce spans for specifically named traced components.

```java
TraceComponent traceComponent = OpenTelemetry.Tracing.getTracer().componentBuilder("io.opentelemetry.contrib.mongodb", "semver:1.0.0");
Span span = traceComponent.spanBuilder("someMethod").startSpan();
```

Overall, this would not change a lot compared to the `TracerFactory` since the levels of indirection until producing an actual span are the same.

Instead of setting the `component` property based on the given Tracer names, those names could also be used as *prefixes* for produced span names (e.g. `<TracerName-SpanName>`). However, with regard to data quality and semantic conventions, a dedicated `component` set on spans is probably preferred.

Instead of using plain strings as an argument for creating new Tracers, a `Resource` identifying an instrumentation library could be used. Such resources must have a _version_ and a _name_ label (there could be semantic convention definitions for those labels). This implementation alternative mainly depends on the availability of the `Resource` data type on an API level (see https://github.com/open-telemetry/opentelemetry-specification/pull/254).

```java
// Create resource for given instrumentation library information (name + version)
Map<String, String> libraryLabels = new HashMap<>();
libraryLabels.put("name", "io.opentelemetry.contrib.mongodb");
libraryLabels.put("version", "1.0.0");
Resource libraryResource = Resource.create(libraryLabels);
// Create tracer for given instrumentation library.
Tracer tracer = OpenTelemetry.getTracerFactory().getTracer(libraryResource);
```

Those given alternatives could be applied to Meters and Metrics in the same way.

## Future possibilities

Based on the Resource information identifying a Tracer or Meter these could be configured (enabled / disabled) programmatically or via external configuration sources (e.g. environment).

Based on this proposal, future "signal producers" (i.e. logs) can use the same or a similar creation approach.