Python Tracing SDK

Tracing with Instana is automatic but if you want even more visibility into custom code, a specific application area, or some in-house component, you can use the Python Tracing SDK of Instana.

Instana Python Tracing SDK

The Instana Python module provides an API to trace any arbitrary part of your application.

You can instrument a section of code for tracing with an API as follows:

from instana.singletons import tracer

  span = tracer.start_span("mywork")
  # The code to be instrumented
  id = user.find_by_name('john.smith')
  span.set_tag('user_id', id)
except Exception as e:

Alternatively, you can use the context manager with the with-as statement, which automatically captures and logs any exceptions that are raised, as follows:

from instana.singletons import tracer

with tracer.start_active_span("mywork") as scope:
  # The code to be instrumented
  id = user.find_by_name('john.smith')
  scope.span.set_tag('user_id', id)

Asynchronous tracing

Some operations that you want to trace might be asynchronous, which means that they return immediately but still continue to work separately from the main sequence of instructions. To trace these operations, for example, with asyncio, you can use async_tracer-related tracing methods as follows:

import asyncio
from instana.singletons import tracer, async_tracer

async def do_work(parent_span):
    with async_tracer.start_active_span('launch_async_work', child_of=parent_span):
        print('Work stared')
        await asyncio.sleep(1)
        print('Work finished!')

with tracer.start_active_span('launch_uvloop') as sync_scope:

Carrying context into new threads

Tracing is local to a thread. If you create a new thread, the context must be carried to that new thread and then picked up. You can instrument the code to carry context in to new threads as follows:

def child_thread_function(parent_span):
    tracer.start_active_span('child_thread_span', child_of=parent_span) as child_scope:
        print('Thread offloaded work goes here')

tracer.start_active_span('parent_thread_span') as parent_scope:
    thread = Thread(target = threaded_function, args = (parent_scope.span, ))

Tracing jobs scheduled to run later

You can instrument jobs that are queued to run later as follows:

# Python 3.8
import asyncio
import datetime
import uvloop
import aiohttp

from instana.singletons import tracer, async_tracer


async def launch_async_calls(parent_span):
    with async_tracer.start_active_span('launch_async_calls', child_of=parent_span):
        async with aiohttp.ClientSession() as session:
            async with session.get('') as resp:
               print(await resp.text())

async def run_at(dt, coro):
    await asyncio.sleep((dt -
    return await coro

with tracer.start_active_span('launch_uvloop') as sync_scope:
    sync_scope.span.set_tag('span.kind', 'entry')
      run_at( + datetime.timedelta(seconds=5),

Adding custom tags to Instana spans

To add custom tags to an Instana span, instrument the following code by using the set_tag method:

with tracer.start_active_span('well_chosen_span_name_here') as scope:
    scope.span.set_tag('custom_tag', 'custom_value')