diff --git a/.changelog/5449.added b/.changelog/5449.added new file mode 100644 index 00000000000..52d73c09635 --- /dev/null +++ b/.changelog/5449.added @@ -0,0 +1 @@ +`docs/examples`: add example on how to manually setup the SDK to get SDK metrics diff --git a/docs/examples/metrics/sdk-metrics/README.rst b/docs/examples/metrics/sdk-metrics/README.rst new file mode 100644 index 00000000000..64c500a3bbc --- /dev/null +++ b/docs/examples/metrics/sdk-metrics/README.rst @@ -0,0 +1,36 @@ +SDK Metrics +=========== + +Some SDK components can emit telemetry about their internal state according to the `semantic conventions for OpenTelemetry SDK metrics `_. At the time of writing these semantic conventions are still in development and in order to have them exported you need to set the ``OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED`` environment variable to ``true``. + +The provided :scm_web:`sdk_metrics.py ` example shows how to setup manually the SDK in order to send them. + +Installation +------------ + +.. code-block:: sh + + pip install -r requirements.txt + +Run the Example +--------------- + +Start an OTLP HTTP collector or compatible backend listening on the default +endpoint, ``http://localhost:4318``. To use a different endpoint, configure +``OTEL_EXPORTER_OTLP_ENDPOINT`` or the signal-specific OTLP exporter +environment variables. + +.. code-block:: sh + + python sdk_metrics.py + +The example sends a span, a log record, and the OpenTelemetry SDK health +metrics emitted by the configured SDK components. + +Useful links +------------ + +- OpenTelemetry_ +- :doc:`../../../api/metrics` + +.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ diff --git a/docs/examples/metrics/sdk-metrics/requirements.txt b/docs/examples/metrics/sdk-metrics/requirements.txt new file mode 100644 index 00000000000..84b530cd773 --- /dev/null +++ b/docs/examples/metrics/sdk-metrics/requirements.txt @@ -0,0 +1,4 @@ +opentelemetry-api==1.44.0 +opentelemetry-exporter-otlp-proto-http==1.44.0 +opentelemetry-sdk==1.44.0 +opentelemetry-semantic-conventions==0.65b0 diff --git a/docs/examples/metrics/sdk-metrics/sdk_metrics.py b/docs/examples/metrics/sdk-metrics/sdk_metrics.py new file mode 100644 index 00000000000..23a9c11d391 --- /dev/null +++ b/docs/examples/metrics/sdk-metrics/sdk_metrics.py @@ -0,0 +1,80 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import os +import time + +from opentelemetry import _logs, metrics, trace +from opentelemetry.exporter.otlp.proto.http._log_exporter import ( + OTLPLogExporter, +) +from opentelemetry.exporter.otlp.proto.http.metric_exporter import ( + OTLPMetricExporter, +) +from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( + OTLPSpanExporter, +) +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import SimpleLogRecordProcessor +from opentelemetry.sdk.metrics import MeterProvider +from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader +from opentelemetry.sdk.resources import Resource +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor + +os.environ.setdefault("OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED", "true") + +resource = Resource.create({"service.name": "sdk-metrics-example"}) + +meter_provider = MeterProvider(resource=resource) +metrics.set_meter_provider(meter_provider) + +# Pass the metrics provider into each SDK component that should report +# internal health metrics. +metric_exporter = OTLPMetricExporter(meter_provider=meter_provider) +metric_reader = PeriodicExportingMetricReader( + metric_exporter, + export_interval_millis=250, # Intentionally low for example purposes only +) +meter_provider.add_metric_reader(metric_reader) + +tracer_provider = TracerProvider( + resource=resource, + meter_provider=meter_provider, +) +tracer_provider.add_span_processor( + SimpleSpanProcessor( + OTLPSpanExporter(meter_provider=meter_provider), + meter_provider=meter_provider, + ) +) +trace.set_tracer_provider(tracer_provider) + +logger_provider = LoggerProvider( + resource=resource, + meter_provider=meter_provider, +) +logger_provider.add_log_record_processor( + SimpleLogRecordProcessor( + OTLPLogExporter(meter_provider=meter_provider), + meter_provider=meter_provider, + ) +) +_logs.set_logger_provider(logger_provider) + +tracer = trace.get_tracer(__name__) +logger = _logs.get_logger(__name__) + +with tracer.start_as_current_span("example-span"): + logger.emit(body="example log record") + # Let the periodic reader export at least once so exporter self-metrics + # are available for the final metrics export. + time.sleep(0.5) + +tracer_provider.force_flush() +logger_provider.force_flush() +meter_provider.force_flush() + +tracer_provider.shutdown() +logger_provider.shutdown() +meter_provider.shutdown()