Docs
DocumentationQuery ReferenceAPI Reference
Open Console→→
DocumentationQuery ReferenceAPI Reference

Platform overview

What is Axiom?QuickstartArchitectureFeatures
Fundamentals
Datasets
Edge deployments
Limits
Performance
Optimize usage
Requirements
Semantic conventions
Glossary
Tour
SecurityRoadmap

Send data

Reference architecturesMethods

Understand data

Console
Query
Builder
Editor
Query results
Visualize
Traces
Metrics
Correlations
Save queries
Stream
Dashboard
Create
Elements
Create
Configure
Element types
Gauge
Heatmap
Log stream
Monitor list
Note
Pie chart
Scatter plot
Statistic
Table
Time series
Sections
Configure
Filter
Annotate
Monitor
Overview
View status
Configure
Examples
Monitor types
Anomaly
Match
Threshold
Alerting
Overview
Configure
Notifier types
Custom Webhook
Discord
Email
Microsoft Teams
Opsgenie
PagerDuty
Slack
Manage
Datasets
Overview
Views
Virtual fields
Access
RBAC
Tokens
CLI
Organization
Audit log
Settings
Usage and billing
Profile
Extend
Overview
AWS Lambda
AWS PrivateLink
Cloudflare Workers
Cloudflare Logpush
Convex
Grafana
Hex
Netlify
Supabase
Tailscale
Terraform
Unkey
Vercel
Intelligence
Overview
Spotlight
AI agents
Overview
MCP Server
Overview
Tools
Query cost limits
Agent-created orgs
Skills
Overview
Axiom alerting
Build dashboards
Control costs
Query metrics
SRE
Translate SPL to APL
Splunk
Overview
Splunk app
Install and configure
Commands
Examples
Portal
How it works
Set up standard mode
Set up transparent mode
Observability Cloud
SPL command support
Examples
Monitor and troubleshoot

Use cases

ObservabilityProduct analytics
LLM observability
Overview
Use Axiom AI SDK
Manual instrumentation
GenAI attributes
Redaction policies

Miscellaneous

LLMs
Overview
List of docs pages
Full docs
Query reference
FAQs
Legal
Acceptable use policy
Cookies
Data processing
HIPAA
Partner agreement
Partner program guide
Privacy policy
SLA
Terms of service
Terms of use

Send OpenTelemetry data from a Python app to Axiom

This guide explains how to send OpenTelemetry data from a Python app to Axiom using the Python OpenTelemetry SDK.

This guide explains how to send OpenTelemetry data from a Python app to Axiom using the Python OpenTelemetry SDK.

Prerequisites

Prerequisites

  • Create an Axiom account.
  • Create a dataset in Axiom where you send your data.
  • Create an API token in Axiom with permissions to ingest data to the dataset you have created.
  • Install Python version 3.7 or higher.

Install required dependencies

To install the required Python dependencies, run the following code in your terminal:

shell
pip install opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation-flask opentelemetry-exporter-otlp Flask

Install dependencies with requirements file

Alternatively, if you use a requirements.txt file in your Python project, add these lines:

text
opentelemetry-api
opentelemetry-sdk
opentelemetry-instrumentation-flask
opentelemetry-exporter-otlp
Flask

Then run the following code in your terminal to install dependencies:

shell
pip install -r requirements.txt

Create an app.py file

Create an app.py file with the following content. This file creates a basic HTTP server using Flask. It also demonstrates the usage of span links to establish relationships between spans across different traces.

python
# app.py

from flask import Flask
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry import trace
from random import randint
import exporter

# Creating a Flask app instance
app = Flask(__name__)

# Automatically instruments Flask app to enable tracing
FlaskInstrumentor().instrument_app(app)

# Retrieving a tracer from the custom exporter
tracer = exporter.service1_tracer

@app.route("/rolldice")
def roll_dice(parent_span=None):
    # Starting a new span for the dice roll. If a parent span is provided, link to its span context.
    with tracer.start_as_current_span("roll_dice_span",
          links=[trace.Link(parent_span.get_span_context())] if parent_span else None) as span:
        # Spans can be created with zero or more Links to other Spans that are related.
        # Links allow creating connections between different traces
        return str(roll())

@app.route("/roll_with_link")
def roll_with_link():
    # Starting a new 'parent_span' which may later link to other spans
    with tracer.start_as_current_span("parent_span") as parent_span:
        # A common scenario is to correlate one or more traces with the current span.
        # This can help in tracing and debugging complex interactions across different parts of the app.
        result = roll_dice(parent_span)
        return f"Dice roll result (with link): {result}"

def roll():
    # Function to generate a random number between 1 and 6
    return randint(1, 6)

if __name__ == "__main__":
    # Starting the Flask server on the specified PORT and enabling debug mode
    app.run(port=8080, debug=True)

Create an exporter.py file

Create an exporter.py file with the following content. This file establishes an OpenTelemetry configuration and sets up an exporter that sends trace data to Axiom.

python
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.resources import Resource, SERVICE_NAME
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

# Define the service name resource for the tracer.
resource = Resource(attributes={
    SERVICE_NAME: "NAME_OF_SERVICE" # Replace `NAME_OF_SERVICE` with the name of the service you want to trace.
})

# Create a TracerProvider with the defined resource for creating tracers.
provider = TracerProvider(resource=resource)

# Configure the OTLP/HTTP Span Exporter with Axiom headers and endpoint.
otlp_exporter = OTLPSpanExporter(
    endpoint="https://AXIOM_DOMAIN/v1/traces",
    headers={
        "Authorization": "Bearer API_TOKEN",
        "X-Axiom-Dataset": "DATASET_NAME"
    }
)

# Create a BatchSpanProcessor with the OTLP exporter to batch and send trace spans.
processor = BatchSpanProcessor(otlp_exporter)
provider.add_span_processor(processor)

# Set the TracerProvider as the global tracer provider.
trace.set_tracer_provider(provider)

# Define a tracer for external use in different parts of the app.
service1_tracer = trace.get_tracer("service1")
Info

Replace NAME_OF_SERVICE with the name of the service you want to trace. This is important for identifying and categorizing trace data, particularly in systems with multiple services.

Replace API_TOKEN with the Axiom API token you have generated. For added security, store the API token in an environment variable.

Replace DATASET_NAME with the name of the Axiom dataset where you send your data.

Replace AXIOM_DOMAIN with the base domain of your edge deployment. For more information, see Edge deployments.

For more information on the libraries imported by the exporter.py file, see the Reference below.

Run the app

Run the following code in your terminal to run the Python project:

macOS/Linux

shell
python3 app.py

Windows

text
py -3 app.py

In your browser, go to http://127.0.0.1:8080/rolldice to interact with your Python app. Each time you load the page, the app displays a random number and sends the collected traces to Axiom.

Observe the telemetry data in Axiom

In Axiom, go the Stream tab and click your dataset. This page displays the traces sent to Axiom and enables you to monitor and analyze your app’s performance and behavior.

Observing the Telemetry data in Axiom image
└Observing the Telemetry data in Axiom image

Dynamic OpenTelemetry traces dashboard

In Axiom, go the Dashboards tab and click OpenTelemetry Traces (python). This pre-built traces dashboard provides further insights into the performance and behavior of your app.

Dynamic OpenTelemetry Traces dashboard
└Dynamic OpenTelemetry Traces dashboard

Send data from an existing Python project

Manual instrumentation

Manual instrumentation in Python with OpenTelemetry involves adding code to create and manage spans around the blocks of code you want to trace. This approach allows for precise control over the trace data.

  1. Import and configure a tracer at the start of your main Python file. For example, use the tracer from the exporter.py configuration.

    python
    import exporter
    tracer = exporter.service1_tracer
  2. Enclose the code blocks in your app that you want to trace within spans. Start and end these spans in your code.

    python
    with tracer.start_as_current_span("operation_name"):
  3. Add relevant metadata and logs to your spans to enrich the trace data, providing more context for your data.

    python
    with tracer.start_as_current_span("operation_name") as span:
        span.set_attribute("key", "value")

Automatic instrumentation

Automatic instrumentation in Python with OpenTelemetry simplifies the process of adding telemetry data to your app. It uses pre-built libraries that automatically instrument the frameworks and libraries.

  1. Install the OpenTelemetry packages designed for specific frameworks like Flask or Django.

    shell
    pip install opentelemetry-instrumentation-flask
  2. Configure your app to use these libraries that automatically generate spans for standard operations.

    python
    from opentelemetry.instrumentation.flask import FlaskInstrumentor
    # This assumes `app` is your Flask app.
    FlaskInstrumentor().instrument_app(app)

After you set them up, these libraries automatically trace relevant operations without additional code changes in your app.

Reference

List of OpenTelemetry trace fields

Field CategoryField NameDescription
Unique Identifiers
_rowidUnique identifier for each row in the trace data.
span_idUnique identifier for the span within the trace.
trace_idUnique identifier for the entire trace.
Timestamps
_systimeSystem timestamp when the trace data was recorded.
_timeTimestamp when the actual event being traced occurred.
HTTP Attributes
attributes.custom["http.host"]Host information where the HTTP request was sent.
attributes.custom["http.server_name"]Server name for the HTTP request.
attributes.http.flavorHTTP protocol version used.
attributes.http.methodHTTP method used for the request.
attributes.http.routeRoute accessed during the HTTP request.
attributes.http.schemeProtocol scheme (HTTP/HTTPS).
attributes.http.status_codeHTTP response status code.
attributes.http.targetSpecific target of the HTTP request.
attributes.http.user_agentUser agent string of the client.
Network Attributes
attributes.net.host.portPort number on the host receiving the request.
attributes.net.peer.portPort number on the peer (client) side.
attributes.custom["net.peer.ip"]IP address of the peer in the network interaction.
Operational Details
durationTime taken for the operation.
kindType of span (for example,, server, client).
nameName of the span.
scopeInstrumentation scope.
service.nameName of the service generating the trace.

List of imported libraries

The exporter.py file imports the following libraries:

from opentelemetry import trace

This module creates and manages trace data in your app. It creates spans and tracers which track the execution flow and performance of your app.

from opentelemetry.sdk.trace import TracerProvider

TracerProvider acts as a container for the configuration of your app’s tracing behavior. It allows you to define how spans are generated and processed, essentially serving as the central point for managing trace creation and propagation in your app.

from opentelemetry.sdk.trace.export import BatchSpanProcessor

BatchSpanProcessor is responsible for batching spans before they're exported. This is an important aspect of efficient trace data management as it aggregates multiple spans into fewer network requests, reducing the overhead on your app’s performance and the tracing backend.

from opentelemetry.sdk.resources import Resource, SERVICE_NAME

The Resource class is used to describe your app’s service attributes, such as its name, version, and environment. This contextual information is attached to the traces and helps in identifying and categorizing trace data, making it easier to filter and analyze in your monitoring setup.

from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

The OTLPSpanExporter is responsible for sending your app’s trace data to a backend that supports the OTLP such as Axiom. It formats the trace data according to the OTLP standards and transmits it over HTTP, ensuring compatibility and standardization in how telemetry data is sent across different systems and services.

Was this page helpful?
Suggest edits on GitHub
On this page
PrerequisitesInstall required dependenciesInstall dependencies with requirements fileCreate an app.py fileCreate an exporter.py fileRun the appObserve the telemetry data in AxiomDynamic OpenTelemetry traces dashboardSend data from an existing Python projectManual instrumentationAutomatic instrumentationReferenceList of OpenTelemetry trace fieldsList of imported libraries