Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#5120](https://github.com/open-telemetry/opentelemetry-python/pull/5120))
- Add WeaverLiveCheck test util
([#5088](https://github.com/open-telemetry/opentelemetry-python/pull/5088))
- Add ability to selectively enable exporting of SDK internal metrics with the `OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED` environment variable.
([#5151](https://github.com/open-telemetry/opentelemetry-python/pull/5151))

## Version 1.41.0/0.62b0 (2026-04-09)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def __init__(
signal: Literal["traces", "metrics", "logs"],
endpoint: UrlParseResult,
meter_provider: MeterProvider | None,
*,
disabled: bool = False,
) -> None:
if signal == "traces":
create_exported = create_otel_sdk_exporter_span_exported
Expand Down Expand Up @@ -104,9 +106,14 @@ def __init__(
self._inflight = create_inflight(meter)
self._exported = create_exported(meter)
self._duration = create_otel_sdk_exporter_operation_duration(meter)
self._disabled = disabled

@contextmanager
def export_operation(self, num_items: int) -> Iterator[ExportResult]:
if self._disabled:
yield ExportResult()
return

start_time = perf_counter()
self._inflight.add(num_items, self._standard_attrs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@
OTEL_EXPORTER_OTLP_HEADERS,
OTEL_EXPORTER_OTLP_INSECURE,
OTEL_EXPORTER_OTLP_TIMEOUT,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.environment_variables._internal import (
parse_boolean_environment_variable,
)
from opentelemetry.sdk.metrics.export import MetricExportResult, MetricsData
from opentelemetry.sdk.resources import Resource as SDKResource
Expand Down Expand Up @@ -392,6 +396,9 @@ def __init__(
signal,
parsed_url,
meter_provider,
disabled=not parse_boolean_environment_variable(
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED
),
)

self._initialize_channel_and_stub()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
from opentelemetry.sdk.environment_variables import (
_OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER,
OTEL_EXPORTER_OTLP_COMPRESSION,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import InMemoryMetricReader
Expand Down Expand Up @@ -387,13 +388,19 @@ def test_otlp_exporter_otlp_compression_envvar(
),
)

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
def test_shutdown(self):
add_TraceServiceServicer_to_server(
TraceServiceServicerWithExportParams(StatusCode.OK),
self.server,
)
exporter = OTLPSpanExporterForTesting(
insecure=True, meter_provider=self.meter_provider
)
self.assertEqual(
self.exporter.export([self.span]), SpanExportResult.SUCCESS
exporter.export([self.span]), SpanExportResult.SUCCESS
)
metrics_data = self.metric_reader.get_metrics_data()
scope_metrics = metrics_data.resource_metrics[0].scope_metrics[0]
Expand All @@ -415,10 +422,10 @@ def test_shutdown(self):
metrics[2].data.data_points[0].attributes
)

self.exporter.shutdown()
exporter.shutdown()
with self.assertLogs(level=WARNING) as warning:
self.assertEqual(
self.exporter.export([self.span]), SpanExportResult.FAILURE
exporter.export([self.span]), SpanExportResult.FAILURE
)
self.assertEqual(
warning.records[0].message,
Expand Down Expand Up @@ -480,6 +487,9 @@ def test_export_over_closed_grpc_channel(self):
system() == "Windows",
"For gRPC + windows there's some added delay in the RPCs which breaks the assertion over amount of time passed.",
)
@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
def test_retry_info_is_respected(self):
mock_trace_service = TraceServiceServicerWithExportParams(
StatusCode.UNAVAILABLE,
Expand Down Expand Up @@ -622,7 +632,13 @@ def test_otlp_headers_from_env(self):
(),
)

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
def test_permanent_failure(self):
exporter = OTLPSpanExporterForTesting(
insecure=True, meter_provider=self.meter_provider
)
with self.assertLogs(level=WARNING) as warning:
add_TraceServiceServicer_to_server(
TraceServiceServicerWithExportParams(
Expand All @@ -631,7 +647,7 @@ def test_permanent_failure(self):
self.server,
)
self.assertEqual(
self.exporter.export([self.span]), SpanExportResult.FAILURE
exporter.export([self.span]), SpanExportResult.FAILURE
)
self.assertEqual(
warning.records[-1].message,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
OTEL_EXPORTER_OTLP_LOGS_HEADERS,
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
OTEL_EXPORTER_OTLP_TIMEOUT,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.environment_variables._internal import (
parse_boolean_environment_variable,
)
from opentelemetry.semconv._incubating.attributes.otel_attributes import (
OtelComponentTypeValues,
Expand Down Expand Up @@ -157,6 +161,9 @@ def __init__(
"logs",
urlparse(self._endpoint),
meter_provider,
disabled=not parse_boolean_environment_variable(
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED
),
)

def _export(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@
OTEL_EXPORTER_OTLP_METRICS_HEADERS,
OTEL_EXPORTER_OTLP_METRICS_TIMEOUT,
OTEL_EXPORTER_OTLP_TIMEOUT,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.environment_variables._internal import (
parse_boolean_environment_variable,
)
from opentelemetry.sdk.metrics._internal.aggregation import Aggregation
from opentelemetry.sdk.metrics.export import ( # noqa: F401
Expand Down Expand Up @@ -222,6 +226,9 @@ def __init__(
"metrics",
urlparse(self._endpoint),
meter_provider,
disabled=not parse_boolean_environment_variable(
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED
),
)

def _export(
Expand Down Expand Up @@ -404,6 +411,9 @@ def set_meter_provider(self, meter_provider: MeterProvider) -> None:
"metrics",
urlparse(self._endpoint),
meter_provider,
disabled=not parse_boolean_environment_variable(
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED
),
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
OTEL_EXPORTER_OTLP_TRACES_HEADERS,
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.environment_variables._internal import (
parse_boolean_environment_variable,
)
from opentelemetry.sdk.trace import ReadableSpan
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
Expand Down Expand Up @@ -152,6 +156,9 @@ def __init__(
"traces",
urlparse(self._endpoint),
meter_provider,
disabled=not parse_boolean_environment_variable(
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED
),
)

def _export(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE,
OTEL_EXPORTER_OTLP_METRICS_TIMEOUT,
OTEL_EXPORTER_OTLP_TIMEOUT,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.metrics import (
Counter,
Expand Down Expand Up @@ -334,6 +335,9 @@ def test_headers_parse_from_env(self):
),
)

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
@patch.object(Session, "post")
def test_success(self, mock_post):
resp = Response()
Expand Down Expand Up @@ -372,6 +376,9 @@ def test_success(self, mock_post):
metrics[2].data.data_points[0].attributes
)

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
@patch.object(Session, "post")
def test_failure(self, mock_post):
resp = Response()
Expand Down Expand Up @@ -1291,6 +1298,9 @@ def test_preferred_aggregation_override(self):
exporter._preferred_aggregation[Histogram], histogram_aggregation
)

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
@patch.object(Session, "post")
def test_retry_timeout(self, mock_post):
exporter = OTLPMetricExporter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
OTEL_EXPORTER_OTLP_LOGS_HEADERS,
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
OTEL_EXPORTER_OTLP_TIMEOUT,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import InMemoryMetricReader
Expand Down Expand Up @@ -467,6 +468,9 @@ def test_2xx_status_code(self, mock_otlp_metric_exporter):
LogRecordExportResult.SUCCESS,
)

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
@patch.object(Session, "post")
def test_retry_timeout(self, mock_post):
exporter = OTLPLogExporter(
Expand Down Expand Up @@ -555,6 +559,9 @@ def test_export_no_collector_available_retryable(self, mock_post):
warning.records[0].message,
)

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
@patch.object(Session, "post")
def test_export_no_collector_available(self, mock_post):
exporter = OTLPLogExporter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
OTEL_EXPORTER_OTLP_TRACES_HEADERS,
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import InMemoryMetricReader
Expand Down Expand Up @@ -287,6 +288,20 @@ def test_2xx_status_code(self, mock_otlp_metric_exporter):
OTLPSpanExporter().export(MagicMock()), SpanExportResult.SUCCESS
)

@patch.dict("os.environ", {}, clear=True)
@patch.object(OTLPSpanExporter, "_export", return_value=Mock(ok=True))
def test_exporter_metrics_disabled_by_default(self, _mock_export):
exporter = OTLPSpanExporter(meter_provider=self.meter_provider)

self.assertEqual(
exporter.export([BASIC_SPAN]), SpanExportResult.SUCCESS
)

self.assertIsNone(self.metric_reader.get_metrics_data())

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
@patch.object(Session, "post")
def test_retry_timeout(self, mock_post):
exporter = OTLPSpanExporter(
Expand Down Expand Up @@ -375,6 +390,9 @@ def test_export_no_collector_available_retryable(self, mock_post):
warning.records[0].message,
)

@patch.dict(
"os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: "true"}
)
@patch.object(Session, "post")
def test_export_no_collector_available(self, mock_post):
exporter = OTLPSpanExporter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
# limitations under the License.

from opentelemetry import metrics as metrics_api
from opentelemetry.sdk.environment_variables import (
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.environment_variables._internal import (
parse_boolean_environment_variable,
)
from opentelemetry.semconv._incubating.metrics.otel_metrics import (
create_otel_sdk_log_created,
)
Expand All @@ -22,6 +28,11 @@ class LoggerMetrics:
def __init__(self, meter_provider: metrics_api.MeterProvider) -> None:
meter = meter_provider.get_meter("opentelemetry-sdk")
self._created_logs = create_otel_sdk_log_created(meter)
self._disabled = not parse_boolean_environment_variable(
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED
)

def emit_log(self) -> None:
if self._disabled:
return
self._created_logs.add(1)
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
OTEL_BLRP_MAX_EXPORT_BATCH_SIZE,
OTEL_BLRP_MAX_QUEUE_SIZE,
OTEL_BLRP_SCHEDULE_DELAY,
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED,
)
from opentelemetry.sdk.environment_variables._internal import (
parse_boolean_environment_variable,
)
from opentelemetry.sdk.resources import Resource
from opentelemetry.semconv._incubating.attributes.otel_attributes import (
Expand Down Expand Up @@ -190,6 +194,9 @@ def __init__(
"logs",
OtelComponentTypeValues.SIMPLE_LOG_PROCESSOR,
meter_provider or get_meter_provider(),
disabled=not parse_boolean_environment_variable(
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED
),
)

def on_emit(self, log_record: ReadWriteLogRecord):
Expand Down Expand Up @@ -304,6 +311,9 @@ def __init__(
OtelComponentTypeValues.BATCHING_LOG_PROCESSOR,
meter_provider or get_meter_provider(),
capacity=max_queue_size,
disabled=not parse_boolean_environment_variable(
OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED
),
),
)

Expand Down
Loading
Loading