From a70e4a0d897e4f33d5e8da20d463c9c5f2abc908 Mon Sep 17 00:00:00 2001 From: Matej Gera <38492574+matej-g@users.noreply.github.com> Date: Wed, 15 Mar 2023 18:36:26 +0100 Subject: [PATCH] Fix use of built-in samplers in SDK configuration (#3176) * Add built-in sampler classes Signed-off-by: Matej Gera * Add entry points for built-in samplers Signed-off-by: Matej Gera * Add CHANGELOG Signed-off-by: Matej Gera * Handle rate arg properly Signed-off-by: Matej Gera * Adjust class and entry points naming Signed-off-by: Matej Gera --------- Signed-off-by: Matej Gera Co-authored-by: Srikanth Chekuri --- CHANGELOG.md | 2 ++ opentelemetry-sdk/pyproject.toml | 8 +++++++ .../sdk/_configuration/__init__.py | 18 ++++++++++++--- .../src/opentelemetry/sdk/trace/sampling.py | 22 ++++++++++++++++++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31dd72bdcc4..9d98c2c5995 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3100](https://github.com/open-telemetry/opentelemetry-python/pull/3100)) - Fix formatting of ConsoleMetricExporter. ([#3197](https://github.com/open-telemetry/opentelemetry-python/pull/3197)) +- Fix use of built-in samplers in SDK configuration + ([#3176](https://github.com/open-telemetry/opentelemetry-python/pull/3176)) - Implement shutdown procedure forOTLP grpc exporters ([#3138](https://github.com/open-telemetry/opentelemetry-python/pull/3138)) - Add exponential histogram diff --git a/opentelemetry-sdk/pyproject.toml b/opentelemetry-sdk/pyproject.toml index bffc677fd00..70d77c57b3a 100644 --- a/opentelemetry-sdk/pyproject.toml +++ b/opentelemetry-sdk/pyproject.toml @@ -41,6 +41,14 @@ sdk = "opentelemetry.sdk.environment_variables" [project.entry-points.opentelemetry_id_generator] random = "opentelemetry.sdk.trace.id_generator:RandomIdGenerator" +[project.entry-points.opentelemetry_traces_sampler] +always_on = "opentelemetry.sdk.trace.sampling:_AlwaysOn" +always_off = "opentelemetry.sdk.trace.sampling:_AlwaysOff" +parentbased_always_on = "opentelemetry.sdk.trace.sampling:_ParentBasedAlwaysOn" +parentbased_always_off = "opentelemetry.sdk.trace.sampling:_ParentBasedAlwaysOff" +traceidratio = "opentelemetry.sdk.trace.sampling:TraceIdRatioBased" +parentbased_traceidratio = "opentelemetry.sdk.trace.sampling:ParentBasedTraceIdRatio" + [project.entry-points.opentelemetry_logger_provider] sdk_logger_provider = "opentelemetry.sdk._logs:LoggerProvider" diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py index c0156decaff..958a50394e9 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py @@ -295,8 +295,20 @@ def _import_sampler(sampler_name: str) -> Optional[Sampler]: return None try: sampler_factory = _import_sampler_factory(sampler_name) - sampler_arg = os.getenv(OTEL_TRACES_SAMPLER_ARG, "") - sampler = sampler_factory(sampler_arg) + arg = None + if sampler_name in ("traceidratio", "parentbased_traceidratio"): + try: + rate = float(os.getenv(OTEL_TRACES_SAMPLER_ARG)) + except (ValueError, TypeError): + _logger.warning( + "Could not convert TRACES_SAMPLER_ARG to float. Using default value 1.0." + ) + rate = 1.0 + arg = rate + else: + arg = os.getenv(OTEL_TRACES_SAMPLER_ARG) + + sampler = sampler_factory(arg) if not isinstance(sampler, Sampler): message = f"Sampler factory, {sampler_factory}, produced output, {sampler}, which is not a Sampler." _logger.warning(message) @@ -304,7 +316,7 @@ def _import_sampler(sampler_name: str) -> Optional[Sampler]: return sampler except Exception as exc: # pylint: disable=broad-except _logger.warning( - "Using default sampler. Failed to initialize custom sampler, %s: %s", + "Using default sampler. Failed to initialize sampler, %s: %s", sampler_name, exc, ) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py index 8af41f3d66e..0236fac6b62 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py @@ -394,6 +394,26 @@ def __init__(self, rate: float): super().__init__(root=root) +class _AlwaysOff(StaticSampler): + def __init__(self, _): + super().__init__(Decision.DROP) + + +class _AlwaysOn(StaticSampler): + def __init__(self, _): + super().__init__(Decision.RECORD_AND_SAMPLE) + + +class _ParentBasedAlwaysOff(ParentBased): + def __init__(self, _): + super().__init__(ALWAYS_OFF) + + +class _ParentBasedAlwaysOn(ParentBased): + def __init__(self, _): + super().__init__(ALWAYS_ON) + + _KNOWN_SAMPLERS = { "always_on": ALWAYS_ON, "always_off": ALWAYS_OFF, @@ -415,7 +435,7 @@ def _get_from_env_or_default() -> Sampler: if trace_sampler in ("traceidratio", "parentbased_traceidratio"): try: rate = float(os.getenv(OTEL_TRACES_SAMPLER_ARG)) - except ValueError: + except (ValueError, TypeError): _logger.warning("Could not convert TRACES_SAMPLER_ARG to float.") rate = 1.0 return _KNOWN_SAMPLERS[trace_sampler](rate)