From b31828bf666671a0189c4e4070a0bc64c66ea298 Mon Sep 17 00:00:00 2001 From: Nathaniel Ruiz Nowell Date: Wed, 23 Sep 2020 15:26:17 -0700 Subject: [PATCH] Add interface to make trace & span id customizable --- docs/api/trace.ids_generator.rst | 7 +++ docs/api/trace.rst | 1 + opentelemetry-api/CHANGELOG.md | 2 + .../src/opentelemetry/trace/__init__.py | 3 ++ .../src/opentelemetry/trace/ids_generator.py | 46 +++++++++++++++++++ opentelemetry-sdk/CHANGELOG.md | 2 + .../src/opentelemetry/sdk/trace/__init__.py | 27 +++-------- .../sdk/trace/propagation/b3_format.py | 6 +-- 8 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 docs/api/trace.ids_generator.rst create mode 100644 opentelemetry-api/src/opentelemetry/trace/ids_generator.py diff --git a/docs/api/trace.ids_generator.rst b/docs/api/trace.ids_generator.rst new file mode 100644 index 00000000000..8f516bb3b1e --- /dev/null +++ b/docs/api/trace.ids_generator.rst @@ -0,0 +1,7 @@ +opentelemetry.trace.ids_generator +================================= + +.. automodule:: opentelemetry.trace.ids_generator + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/api/trace.rst b/docs/api/trace.rst index 65d9b4d8c88..81f11e3dd09 100644 --- a/docs/api/trace.rst +++ b/docs/api/trace.rst @@ -8,6 +8,7 @@ Submodules trace.status trace.span + trace.ids_generator Module contents --------------- diff --git a/opentelemetry-api/CHANGELOG.md b/opentelemetry-api/CHANGELOG.md index 3d0bcd80052..91a822890bd 100644 --- a/opentelemetry-api/CHANGELOG.md +++ b/opentelemetry-api/CHANGELOG.md @@ -6,6 +6,8 @@ ([#1123](https://github.com/open-telemetry/opentelemetry-python/pull/1123)) - Store `int`s as `int`s in the global Configuration object ([#1118](https://github.com/open-telemetry/opentelemetry-python/pull/1118)) +- Allow for Custom Trace and Span IDs Generation - `IdsGenerator` for TracerProvider + ([#1153](https://github.com/open-telemetry/opentelemetry-python/pull/1153)) ## Version 0.13b0 diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 1795192254f..e2d4108fd31 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -77,6 +77,7 @@ from contextlib import contextmanager from logging import getLogger +from opentelemetry.trace.ids_generator import IdsGenerator, RandomIdsGenerator from opentelemetry.trace.propagation import ( get_current_span, set_span_in_context, @@ -435,6 +436,7 @@ def get_tracer_provider() -> TracerProvider: __all__ = [ "DEFAULT_TRACE_OPTIONS", "DEFAULT_TRACE_STATE", + "IdsGenerator", "INVALID_SPAN", "INVALID_SPAN_CONTEXT", "INVALID_SPAN_ID", @@ -445,6 +447,7 @@ def get_tracer_provider() -> TracerProvider: "Link", "LinkBase", "ParentSpan", + "RandomIdsGenerator", "Span", "SpanContext", "SpanKind", diff --git a/opentelemetry-api/src/opentelemetry/trace/ids_generator.py b/opentelemetry-api/src/opentelemetry/trace/ids_generator.py new file mode 100644 index 00000000000..1ed2e2fec2a --- /dev/null +++ b/opentelemetry-api/src/opentelemetry/trace/ids_generator.py @@ -0,0 +1,46 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import abc +import random + + +class IdsGenerator(abc.ABC): + @abc.abstractmethod + def generate_span_id(self) -> int: + """Get a new span ID. + + Returns: + A 64-bit int for use as a span ID + """ + + @abc.abstractmethod + def generate_trace_id(self) -> int: + """Get a new trace ID. + + Returns: + A 128-bit int for use as a trace ID + """ + + +class RandomIdsGenerator(IdsGenerator): + """The default IDs generator for TracerProvider which randomly generates all + bits when generating IDs. + """ + + def generate_span_id(self) -> int: + return random.getrandbits(64) + + def generate_trace_id(self) -> int: + return random.getrandbits(128) diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index c9b4c3538db..cdf645311ec 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -6,6 +6,8 @@ ([#1128](https://github.com/open-telemetry/opentelemetry-python/pull/1128)) - Add support for `OTEL_BSP_MAX_QUEUE_SIZE`, `OTEL_BSP_SCHEDULE_DELAY_MILLIS`, `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` and `OTEL_BSP_EXPORT_TIMEOUT_MILLIS` environment variables ([#1105](https://github.com/open-telemetry/opentelemetry-python/pull/1120)) +- Allow for Custom Trace and Span IDs Generation - `IdsGenerator` for TracerProvider + ([#1153](https://github.com/open-telemetry/opentelemetry-python/pull/1153)) ## Version 0.13b0 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 13819ed35b0..0134ec7e775 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -663,24 +663,6 @@ def record_exception(self, exception: Exception) -> None: ) -def generate_span_id() -> int: - """Get a new random span ID. - - Returns: - A random 64-bit int for use as a span ID - """ - return random.getrandbits(64) - - -def generate_trace_id() -> int: - """Get a new random trace ID. - - Returns: - A random 128-bit int for use as a trace ID - """ - return random.getrandbits(128) - - class Tracer(trace_api.Tracer): """See `opentelemetry.trace.Tracer`. @@ -733,7 +715,7 @@ def start_span( # pylint: disable=too-many-locals if parent_context is None or not parent_context.is_valid: parent = parent_context = None - trace_id = generate_trace_id() + trace_id = self.source.ids_generator.generate_trace_id() trace_flags = None trace_state = None else: @@ -757,7 +739,7 @@ def start_span( # pylint: disable=too-many-locals ) context = trace_api.SpanContext( trace_id, - generate_span_id(), + self.source.ids_generator.generate_span_id(), is_remote=False, trace_flags=trace_flags, trace_state=trace_state, @@ -826,10 +808,15 @@ def __init__( active_span_processor: Union[ SynchronousMultiSpanProcessor, ConcurrentMultiSpanProcessor ] = None, + ids_generator: trace_api.IdsGenerator = None, ): self._active_span_processor = ( active_span_processor or SynchronousMultiSpanProcessor() ) + if ids_generator is None: + self.ids_generator = trace_api.RandomIdsGenerator() + else: + self.ids_generator = ids_generator self.resource = resource self.sampler = sampler self._atexit_handler = None diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/b3_format.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/b3_format.py index c2b12f33f5a..33a8a7fac8d 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/b3_format.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/b3_format.py @@ -17,7 +17,6 @@ import opentelemetry.trace as trace from opentelemetry.context import Context -from opentelemetry.sdk.trace import generate_span_id, generate_trace_id from opentelemetry.trace.propagation.textmap import ( Getter, Setter, @@ -103,8 +102,9 @@ def extract( self._trace_id_regex.fullmatch(trace_id) is None or self._span_id_regex.fullmatch(span_id) is None ): - trace_id = generate_trace_id() - span_id = generate_span_id() + ids_generator = trace.RandomIdsGenerator() + trace_id = ids_generator.generate_trace_id() + span_id = ids_generator.generate_span_id() sampled = "0" else: