Skip to content

Commit

Permalink
Add simple scope configuration to Tracer, Meter, Logger (#3877)
Browse files Browse the repository at this point in the history
Fixes #3867.

This introduces the concept of scope-level configuration for Tracer,
Meter, and Logger. Notes:

- TracerProvider, MeterProvider, and LoggerProvider have a scope config
provider function, which accepts an `InstrumentationScope` and returns
the relevant scope config. This function is invoked when a Tracer,
Meter, Logger is created, and the resulting scope config dictates the
behavior of resulting Tracers, Meters, Loggers. Computing the config on
scope creation avoids doing extra work on the hot path.
- If TracerProvider, MeterProvider, LoggerProvider supports updating
configuration, the function can be updated, at which point the scope
config of outstanding Tracer, Meter, Logger will be re-computed. This
accommodates emerging dynamic config use cases.
- A function as the mechanism to determine relevant scope config to
maximize flexibility. However, implementations are encourages to provide
syntactic sugar / helpers for accommodating popular use cases: select
one or more scopes by name or with pattern matching, disable one or more
selected scopes, disable all scopes by default and enable one or more
selective scopes.
- Scope config is simple at the moment, consisting of on the ability to
enable / disable a particular Tracer, Meter, Logger. When a disabled,
use the respective noop Tracer, Meter, Logger.
- Scope config parameters are expected to evolve over time. When it
makes sense, there should be consistency across signals.
- Java prototype available for this proposal:
open-telemetry/opentelemetry-java#6201

Leaving as a draft for now because its not ready to merge, but I am
actively soliciting feedback. If / when we agree on direction, I'll go
back and add the appropriate experimental indications.
  • Loading branch information
jack-berg committed Apr 8, 2024
1 parent ebc157f commit 223c907
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 15 deletions.
69 changes: 63 additions & 6 deletions specification/logs/sdk.md
@@ -1,6 +1,6 @@
# Logs SDK

**Status**: [Stable](../document-status.md)
**Status**: [Stable](../document-status.md), except where otherwise specified

<details>
<summary>Table of Contents</summary>
Expand All @@ -11,9 +11,11 @@
* [LoggerProvider Creation](#loggerprovider-creation)
* [Logger Creation](#logger-creation)
* [Configuration](#configuration)
+ [LoggerConfigurator](#loggerconfigurator)
* [Shutdown](#shutdown)
* [ForceFlush](#forceflush)
- [Logger](#logger)
* [LoggerConfig](#loggerconfig)
- [Additional LogRecord interfaces](#additional-logrecord-interfaces)
* [ReadableLogRecord](#readablelogrecord)
* [ReadWriteLogRecord](#readwritelogrecord)
Expand Down Expand Up @@ -69,11 +71,17 @@ working `Logger` MUST be returned as a fallback rather than returning null or
throwing an exception, its `name` SHOULD keep the original invalid value, and a
message reporting that the specified value is invalid SHOULD be logged.

**Status**: [Experimental](../document-status.md) - The `LoggerProvider` MUST
compute the relevant [LoggerConfig](#loggerconfig) using the
configured [LoggerConfigurator](#loggerconfigurator), and create
a `Logger` whose behavior conforms to that `LoggerConfig`.

### Configuration

Configuration (i.e. [LogRecordProcessors](#logrecordprocessor)) MUST be owned
by the the `LoggerProvider`. The configuration MAY be applied at the time of
`LoggerProvider` creation if appropriate.
Configuration (
i.e. [LogRecordProcessors](#logrecordprocessor) and (**experimental**) [LoggerConfigurator](#loggerconfigurator))
MUST be owned by the `LoggerProvider`. The configuration MAY be applied at the
time of `LoggerProvider` creation if appropriate.

The `LoggerProvider` MAY provide methods to update the configuration. If
configuration is updated (e.g., adding a `LogRecordProcessor`), the updated
Expand All @@ -83,6 +91,37 @@ after the configuration change). Note: Implementation-wise, this could mean
that `Logger` instances have a reference to their `LoggerProvider` and access
configuration only via this reference.

#### LoggerConfigurator

**Status**: [Experimental](../document-status.md)

A `LoggerConfigurator` is a function which computes
the [LoggerConfig](#loggerconfig) for a [Logger](#logger).

The function MUST accept the following parameter:

* `logger_scope`:
The [`InstrumentationScope`](../glossary.md#instrumentation-scope) of
the `Logger`.

The function MUST return the relevant `LoggerConfig`, or some signal indicating
that the [default LoggerConfig](#loggerconfig) should be used. This signal MAY
be nil, null, empty, or an instance of the default `LoggerConfig` depending on
what is idiomatic in the language.

This function is called when a `Logger` is first created, and for each
outstanding `Logger` when a `LoggerProvider`'s `LoggerConfigurator` is
updated (if updating is supported). Therefore, it is important that it returns
quickly.

`LoggerConfigurator` is modeled as a function to maximize flexibility.
However, implementations MAY provide shorthand or helper functions to
accommodate common use cases:

* Select one or more loggers by name, with exact match or pattern matching.
* Disable one or more specific loggers.
* Disable all loggers, and selectively enable one or more specific loggers.

### Shutdown

This method provides a way for provider to do any cleanup required.
Expand Down Expand Up @@ -124,8 +163,26 @@ registered [LogRecordProcessors](#logrecordprocessor).

## Logger

Note that `Logger`s should not be responsible for configuration. This should be
the responsibility of the `LoggerProvider` instead.
**Status**: [Experimental](../document-status.md) - `Logger` MUST behave
according to the [LoggerConfig](#loggerconfig) computed
during [logger creation](#logger-creation). If the `LoggerProvider` supports
updating the [LoggerConfigurator](#loggerconfigurator), then upon update
the `Logger` MUST be updated to behave according to the new `LoggerConfig`.

### LoggerConfig

**Status**: [Experimental](../document-status.md)

A `LoggerConfig` defines various configurable aspects of a `Logger`'s behavior.
It consists of the following parameters:

* `disabled`: A boolean indication of whether the logger is enabled.

If not explicitly set, the `disabled` parameter SHOULD default to `false` (
i.e. `Logger`s are enabled by default).

If a `Logger` is disabled, it MUST behave equivalently
to [No-op Logger](./noop.md#logger).

## Additional LogRecord interfaces

Expand Down
68 changes: 64 additions & 4 deletions specification/metrics/sdk.md
Expand Up @@ -15,6 +15,7 @@ linkTitle: SDK
* [MeterProvider Creation](#meterprovider-creation)
* [Meter Creation](#meter-creation)
* [Configuration](#configuration)
+ [MeterConfigurator](#meterconfigurator)
* [Shutdown](#shutdown)
* [ForceFlush](#forceflush)
* [View](#view)
Expand All @@ -41,6 +42,7 @@ linkTitle: SDK
+ [Synchronous instrument cardinality limits](#synchronous-instrument-cardinality-limits)
+ [Asynchronous instrument cardinality limits](#asynchronous-instrument-cardinality-limits)
- [Meter](#meter)
* [MeterConfig](#meterconfig)
* [Duplicate instrument registration](#duplicate-instrument-registration)
+ [Name conflict](#name-conflict)
* [Instrument name](#instrument-name)
Expand Down Expand Up @@ -128,12 +130,18 @@ When a Schema URL is passed as an argument when creating a `Meter` the emitted
telemetry for that `Meter` MUST be associated with the Schema URL, provided
that the emitted data format is capable of representing such association.

**Status**: [Experimental](../document-status.md) - The `MeterProvider` MUST
compute the relevant [MeterConfig](#meterconfig) using the
configured [MeterConfigurator](#meterconfigurator), and create
a `Meter` whose behavior conforms to that `MeterConfig`.

### Configuration

Configuration (i.e. [MetricExporters](#metricexporter),
[MetricReaders](#metricreader) and [Views](#view)) MUST be owned by the
`MeterProvider`. The configuration MAY be applied at the time of `MeterProvider`
creation if appropriate.
Configuration (
i.e. [MetricExporters](#metricexporter), [MetricReaders](#metricreader), [Views](#view),
and (**experimental**) [MeterConfigurator](#meterconfigurator)) MUST be
owned by the `MeterProvider`. The configuration MAY be applied at the time
of `MeterProvider` creation if appropriate.

The `MeterProvider` MAY provide methods to update the configuration. If
configuration is updated (e.g., adding a `MetricReader`), the updated
Expand All @@ -143,6 +151,37 @@ the configuration change). Note: Implementation-wise, this could mean that
`Meter` instances have a reference to their `MeterProvider` and access
configuration only via this reference.

#### MeterConfigurator

**Status**: [Experimental](../document-status.md)

A `MeterConfigurator` is a function which computes
the [MeterConfig](#meterconfig) for a [Meter](#meter).

The function MUST accept the following parameter:

* `meter_scope`:
The [`InstrumentationScope`](../glossary.md#instrumentation-scope) of
the `Meter`.

The function MUST return the relevant `MeterConfig`, or some signal indicating
that the [default MeterConfig](#meterconfig) should be used. This signal MAY
be nil, null, empty, or an instance of the default `MeterConfig` depending on
what is idiomatic in the language.

This function is called when a `Meter` is first created, and for each
outstanding `Meter` when a `MeterProvider`'s `MeterConfigurator` is
updated (if updating is supported). Therefore, it is important that it returns
quickly.

`MeterConfigurator` is modeled as a function to maximize flexibility.
However, implementations MAY provide shorthand or helper functions to
accommodate common use cases:

* Select one or more Meters by name, with exact match or pattern matching.
* Disable one or more specific Meters.
* Disable all Meters, and selectively enable one or more specific Meters.

### Shutdown

This method provides a way for provider to do any cleanup required.
Expand Down Expand Up @@ -796,6 +835,27 @@ temporality.
Distinct meters MUST be treated as separate namespaces for the purposes of detecting
[duplicate instrument registrations](#duplicate-instrument-registration).

**Status**: [Experimental](../document-status.md) - `Meter` MUST behave
according to the [MeterConfig](#meterconfig) computed
during [Meter creation](#meter-creation). If the `MeterProvider` supports
updating the [MeterConfigurator](#meterconfigurator), then upon update
the `Meter` MUST be updated to behave according to the new `MeterConfig`.

### MeterConfig

**Status**: [Experimental](../document-status.md)

A `MeterConfig` defines various configurable aspects of a `Meter`'s behavior.
It consists of the following parameters:

* `disabled`: A boolean indication of whether the Meter is enabled.

If not explicitly set, the `disabled` parameter SHOULD default to `false` (
i.e. `Meter`s are enabled by default).

If a `Meter` is disabled, it MUST behave equivalently
to [No-op Meter](./noop.md#meter).

### Duplicate instrument registration

A _duplicate instrument registration_ occurs when more than one Instrument of
Expand Down
73 changes: 68 additions & 5 deletions specification/trace/sdk.md
Expand Up @@ -4,7 +4,7 @@ linkTitle: SDK

# Tracing SDK

**Status**: [Stable](../document-status.md)
**Status**: [Stable](../document-status.md), except where otherwise specified

<details>
<summary>Table of Contents</summary>
Expand All @@ -14,8 +14,11 @@ linkTitle: SDK
- [Tracer Provider](#tracer-provider)
* [Tracer Creation](#tracer-creation)
* [Configuration](#configuration)
+ [TracerConfigurator](#tracerconfigurator)
* [Shutdown](#shutdown)
* [ForceFlush](#forceflush)
- [Tracer](#tracer)
* [TracerConfig](#tracerconfig)
- [Additional Span Interfaces](#additional-span-interfaces)
- [Sampling](#sampling)
* [Recording Sampled reaction table](#recording-sampled-reaction-table)
Expand Down Expand Up @@ -68,12 +71,18 @@ The input provided by the user MUST be used to create
an [`InstrumentationScope`](../glossary.md#instrumentation-scope) instance which
is stored on the created `Tracer`.

**Status**: [Experimental](../document-status.md) - The `TracerProvider` MUST
compute the relevant [TracerConfig](#tracerconfig) using the
configured [TracerConfigurator](#tracerconfigurator), and create
a `Tracer` whose behavior conforms to that `TracerConfig`.

### Configuration

Configuration (i.e., [SpanProcessors](#span-processor), [IdGenerator](#id-generators),
[SpanLimits](#span-limits) and [`Sampler`](#sampling)) MUST be owned by the
the `TracerProvider`. The configuration MAY be applied at the time of `TracerProvider`
creation if appropriate.
Configuration (
i.e., [SpanProcessors](#span-processor), [IdGenerator](#id-generators), [SpanLimits](#span-limits), [`Sampler`](#sampling),
and (**experimental**) [TracerConfigurator](#tracerconfigurator)) MUST be
owned by the `TracerProvider`. The configuration MAY be applied at the time
of `TracerProvider` creation if appropriate.

The TracerProvider MAY provide methods to update the configuration. If
configuration is updated (e.g., adding a `SpanProcessor`),
Expand All @@ -84,6 +93,37 @@ Note: Implementation-wise, this could mean that `Tracer` instances have a
reference to their `TracerProvider` and access configuration only via this
reference.

#### TracerConfigurator

**Status**: [Experimental](../document-status.md)

A `TracerConfigurator` is a function which computes
the [TracerConfig](#tracerconfig) for a [Tracer](#tracer).

The function MUST accept the following parameter:

* `tracer_scope`:
The [`InstrumentationScope`](../glossary.md#instrumentation-scope) of
the `Tracer`.

The function MUST return the relevant `TracerConfig`, or some signal indicating
that the [default TracerConfig](#tracerconfig) should be used. This signal MAY
be nil, null, empty, or an instance of the default `TracerConfig` depending on
what is idiomatic in the language.

This function is called when a `Tracer` is first created, and for each
outstanding `Tracer` when a `TracerProvider`'s `TracerConfigurator` is
updated (if updating is supported). Therefore, it is important that it returns
quickly.

`TracerConfigurator` is modeled as a function to maximize flexibility.
However, implementations MAY provide shorthand or helper functions to
accommodate common use cases:

* Select one or more Tracers by name, with exact match or pattern matching.
* Disable one or more specific Tracers.
* Disable all Tracers, and selectively enable one or more specific Tracers.

### Shutdown

This method provides a way for provider to do any cleanup required.
Expand Down Expand Up @@ -116,6 +156,29 @@ make the flush timeout configurable.

`ForceFlush` MUST invoke `ForceFlush` on all registered `SpanProcessors`.

## Tracer

**Status**: [Experimental](../document-status.md) - `Tracer` MUST behave
according to the [TracerConfig](#tracerconfig) computed
during [Tracer creation](#tracer-creation). If the `TracerProvider` supports
updating the [TracerConfigurator](#tracerconfigurator), then upon update
the `Tracer` MUST be updated to behave according to the new `TracerConfig`.

### TracerConfig

**Status**: [Experimental](../document-status.md)

A `TracerConfig` defines various configurable aspects of a `Tracer`'s behavior.
It consists of the following parameters:

* `disabled`: A boolean indication of whether the Tracer is enabled.

If not explicitly set, the `disabled` parameter SHOULD default to `false` (
i.e. `Tracer`s are enabled by default).

If a `Tracer` is disabled, it MUST behave equivalently
to [No-op Tracer](./api.md#behavior-of-the-api-in-the-absence-of-an-installed-sdk).

## Additional Span Interfaces

The [API-level definition for Span's interface](api.md#span-operations)
Expand Down

0 comments on commit 223c907

Please sign in to comment.