OpenTelemetry Python Instrumentation

Get up and running with OpenTelemetry in just a few quick steps! The setup process consists of two phases--getting OpenTelemetry installed and configured, and then validating that configuration to ensure that data is being sent as expected. This guide explains how to download, install, and run OpenTelemetry in Python.


  • Python 3.4 or newer
  • An app to add OpenTelemetry to

We follow OpenTelemetry python instrumentation library. We shall be exporting data in Jaeger Thrift protocol.

pip3 install opentelemetry-distro
pip3 install opentelemetry-instrumentation
pip3 install opentelemetry-exporter-otlp

If it hangs while installing grpcio during pip3 install opentelemetry-exporter-otlp then follow below steps as suggested in this stackoverflow link

  • pip3 install --upgrade pip
  • python3 -m pip install --upgrade setuptools
  • pip3 install --no-cache-dir --force-reinstall -Iv grpcio
opentelemetry-bootstrap --action=install

The above command inspects the active Python site-packages and figures out which instrumentation packages the user might want to install and installs them for you.


If it says cannot find command opentelemetry-bootstrap then you need to specify the path of the file. In ubuntu, it is at /home/ubuntu/.local/bin/opentelemetry-bootstrap. So your command becomes, /home/ubuntu/.local/bin/opentelemetry-bootstrap --action=install

Run Command#

OTEL_SERVICE_NAME=<service_name> OTEL_EXPORTER_OTLP_ENDPOINT="<IP of SigNoz Backend>:4317" opentelemetry-instrument <your run command>

<service_name> is the name of service you want

<your_run_command> can be python3 or flask run

  • If opentelemetry-instrument command is not found then use full path of executable. In ubuntu it is at /home/ubuntu/.local/bin/opentelemetry-instrument
  • Remember to allow incoming requests to port 4317 of machine where SigNoz backend is hosted

Troubleshooting your installation#

If spans are not being reported to SigNoz, try running in debug mode by setting OTEL_LOG_LEVEL=debug:

The debug log level will print out the configuration information. It will also emit every span to the console, which should look something like:

Span {
attributes: {},
links: [],
events: [],
status: { code: 0 },
endTime: [ 1597810686, 885498645 ],
_ended: true,
_duration: [ 0, 43333 ],
name: 'bar',
spanContext: {
traceId: 'eca3cc297720bd705e734f4941bca45a',
spanId: '891016e5f8c134ad',
traceFlags: 1,
traceState: undefined
parentSpanId: 'cff3a2c6bfd4bbef',
kind: 0,
startTime: [ 1597810686, 885455312 ],
resource: Resource { labels: [Object] },
instrumentationLibrary: { name: 'example', version: '*' },
_logger: ConsoleLogger {
debug: [Function],
info: [Function],
warn: [Function],
error: [Function]
_traceParams: {
numberOfAttributesPerSpan: 32,
numberOfLinksPerSpan: 32,
numberOfEventsPerSpan: 128
_spanProcessor: MultiSpanProcessor { _spanProcessors: [Array] }