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

Adds support OTEL_SDK_DISABLED environment variable #3648

2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#3751](https://github.com/open-telemetry/opentelemetry-python/pull/3751))
- bump mypy to 0.982
([#3776](https://github.com/open-telemetry/opentelemetry-python/pull/3776))
- Add support for OTEL_SDK_DISABLED environment variable
([#3648](https://github.com/open-telemetry/opentelemetry-python/pull/3648))

## Version 1.23.0/0.44b0 (2024-02-23)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from opentelemetry.sdk.environment_variables import (
OTEL_ATTRIBUTE_COUNT_LIMIT,
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT,
OTEL_SDK_DISABLED,
)
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.util import ns_to_iso_str
Expand Down Expand Up @@ -607,6 +608,8 @@ def __init__(
self._multi_log_record_processor = (
multi_log_record_processor or SynchronousMultiLogRecordProcessor()
)
disabled = environ.get(OTEL_SDK_DISABLED, "")
self._disabled = disabled.lower().strip() == "true"
self._at_exit_handler = None
if shutdown_on_exit:
self._at_exit_handler = atexit.register(self.shutdown)
Expand All @@ -621,6 +624,9 @@ def get_logger(
version: Optional[str] = None,
schema_url: Optional[str] = None,
) -> Logger:
if self._disabled:
_logger.warning("SDK is disabled.")
return NoOpLogger(name, version=version, schema_url=schema_url)
return Logger(
self._resource,
self._multi_log_record_processor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.

OTEL_SDK_DISABLED = "OTEL_SDK_DISABLED"
"""
.. envvar:: OTEL_SDK_DISABLED

The :envvar:`OTEL_SDK_DISABLED` environment variable disables the SDK for all signals
Default: "false"
"""

OTEL_RESOURCE_ATTRIBUTES = "OTEL_RESOURCE_ATTRIBUTES"
"""
.. envvar:: OTEL_RESOURCE_ATTRIBUTES
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from atexit import register, unregister
from logging import getLogger
from os import environ
from threading import Lock
from time import time_ns
from typing import Optional, Sequence
Expand All @@ -32,6 +33,7 @@
)
from opentelemetry.metrics import UpDownCounter as APIUpDownCounter
from opentelemetry.metrics import _Gauge as APIGauge
from opentelemetry.sdk.environment_variables import OTEL_SDK_DISABLED
from opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError
from opentelemetry.sdk.metrics._internal.instrument import (
_Counter,
Expand Down Expand Up @@ -394,6 +396,8 @@ def __init__(
self._measurement_consumer = SynchronousMeasurementConsumer(
sdk_config=self._sdk_config
)
disabled = environ.get(OTEL_SDK_DISABLED, "")
self._disabled = disabled.lower().strip() == "true"

if shutdown_on_exit:
self._atexit_handler = register(self.shutdown)
Expand Down Expand Up @@ -512,6 +516,10 @@ def get_meter(
schema_url: Optional[str] = None,
) -> Meter:

if self._disabled:
_logger.warning("SDK is disabled.")
return NoOpMeter(name, version=version, schema_url=schema_url)

if self._shutdown:
_logger.warning(
"A shutdown `MeterProvider` can not provide a `Meter`"
Expand Down
8 changes: 7 additions & 1 deletion opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT,
OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT,
OTEL_LINK_ATTRIBUTE_COUNT_LIMIT,
OTEL_SDK_DISABLED,
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT,
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT,
OTEL_SPAN_EVENT_COUNT_LIMIT,
Expand All @@ -63,7 +64,7 @@
InstrumentationInfo,
InstrumentationScope,
)
from opentelemetry.trace import SpanContext
from opentelemetry.trace import NoOpTracer, SpanContext
from opentelemetry.trace.status import Status, StatusCode
from opentelemetry.util import types

Expand Down Expand Up @@ -1176,6 +1177,8 @@ def __init__(
sampler = sampling._get_from_env_or_default()
self.sampler = sampler
self._span_limits = span_limits or SpanLimits()
disabled = environ.get(OTEL_SDK_DISABLED, "")
self._disabled = disabled.lower().strip() == "true"
self._atexit_handler = None

if shutdown_on_exit:
Expand All @@ -1191,6 +1194,9 @@ def get_tracer(
instrumenting_library_version: typing.Optional[str] = None,
schema_url: typing.Optional[str] = None,
) -> "trace_api.Tracer":
if self._disabled:
logger.warning("SDK is disabled.")
return NoOpTracer()
if not instrumenting_module_name: # Reject empty strings too.
instrumenting_module_name = ""
logger.error("get_tracer called with missing module name.")
Expand Down
9 changes: 8 additions & 1 deletion opentelemetry-sdk/tests/logs/test_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
# pylint: disable=protected-access

import unittest
from unittest.mock import patch
from unittest.mock import Mock, patch

from opentelemetry.sdk._logs import LoggerProvider
from opentelemetry.sdk._logs._internal import (
NoOpLogger,
SynchronousMultiLogRecordProcessor,
)
from opentelemetry.sdk.environment_variables import OTEL_SDK_DISABLED
from opentelemetry.sdk.resources import Resource


Expand Down Expand Up @@ -61,6 +63,11 @@ def test_get_logger(self):
logger._instrumentation_scope.schema_url, "schema_url"
)

@patch.dict("os.environ", {OTEL_SDK_DISABLED: "true"})
def test_get_logger_with_sdk_disabled(self):
logger = LoggerProvider().get_logger(Mock())
self.assertIsInstance(logger, NoOpLogger)

@patch.object(Resource, "create")
def test_logger_provider_init(self, resource_patch):
logger_provider = LoggerProvider()
Expand Down
6 changes: 6 additions & 0 deletions opentelemetry-sdk/tests/metrics/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from unittest.mock import MagicMock, Mock, patch

from opentelemetry.metrics import NoOpMeter
from opentelemetry.sdk.environment_variables import OTEL_SDK_DISABLED
from opentelemetry.sdk.metrics import (
Counter,
Histogram,
Expand Down Expand Up @@ -465,6 +466,11 @@ def test_create_observable_up_down_counter(self):
)
self.assertEqual(observable_up_down_counter.name, "name")

@patch.dict("os.environ", {OTEL_SDK_DISABLED: "true"})
def test_get_meter_with_sdk_disabled(self):
meter_provider = MeterProvider()
self.assertIsInstance(meter_provider.get_meter(Mock()), NoOpMeter)


class InMemoryMetricExporter(MetricExporter):
def __init__(self):
Expand Down
9 changes: 9 additions & 0 deletions opentelemetry-sdk/tests/trace/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

# pylint: disable=too-many-lines
# pylint: disable=no-member

import shutil
import subprocess
Expand All @@ -33,6 +34,7 @@
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT,
OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT,
OTEL_LINK_ATTRIBUTE_COUNT_LIMIT,
OTEL_SDK_DISABLED,
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT,
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT,
OTEL_SPAN_EVENT_COUNT_LIMIT,
Expand Down Expand Up @@ -162,6 +164,13 @@ def test_tracer_provider_accepts_concurrent_multi_span_processor(self):
span_processor, tracer_provider._active_span_processor
)

@mock.patch.dict("os.environ", {OTEL_SDK_DISABLED: "true"})
def test_get_tracer_with_sdk_disabled(self):
tracer_provider = trace.TracerProvider()
self.assertIsInstance(
tracer_provider.get_tracer(Mock()), trace_api.NoOpTracer
)


class TestTracerSampling(unittest.TestCase):
def tearDown(self):
Expand Down
Loading