OTel SDK — Python
Instrument a Python application to send traces directly to xScaler using the OpenTelemetry Python SDK over OTLP/HTTP.
:::warning Required headers
Both headers must be present in the OTLPSpanExporter:
Authorization: "Bearer <token>"X-Scope-OrgID: "<tenant-id>":::
Install dependencies
pip install opentelemetry-sdk \
opentelemetry-exporter-otlp-proto-http
Setup and instrumentation
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
# Configure the exporter
exporter = OTLPSpanExporter(
endpoint="https://euw1-01.t.xscalerlabs.com/otlp/v1/traces",
headers={
"Authorization": "Bearer <token>",
"X-Scope-OrgID": "<tenant-id>",
}
)
# Build the tracer provider
resource = Resource.create({"service.name": "my-service", "service.version": "1.0.0"})
provider = TracerProvider(resource=resource)
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("my-service")
:::note Full OTLP path required
Unlike the OpenTelemetry Collector exporter (which only takes the base host), the Python SDK exporter requires the full path including /otlp/v1/traces.
:::
Instrument your code
with tracer.start_as_current_span("handle-request") as span:
span.set_attribute("http.method", "GET")
span.set_attribute("http.route", "/api/users")
with tracer.start_as_current_span("query-database"):
# simulate database call
import time; time.sleep(0.01)
Load credentials from environment variables
import os
exporter = OTLPSpanExporter(
endpoint="https://euw1-01.t.xscalerlabs.com/otlp/v1/traces",
headers={
"Authorization": f"Bearer {os.environ['XSCALER_TOKEN']}",
"X-Scope-OrgID": os.environ["XSCALER_TENANT_ID"],
}
)
Verify in the portal
Once traces are flowing, open the Traces section of the xScaler portal and click the Overview tab. You should see live values for Ingest rate and Spans/s within a minute of sending spans.
To inspect a specific tenant, click the Tenants tab, select the tenant, then open the Monitoring tab for per-tenant ingest rate charts, bytes ingested, and discard reasons.
Troubleshooting
Traces not appearing
- Verify
endpointincludes the full path:.../otlp/v1/traces. - Enable debug logging:
import logging; logging.basicConfig(level=logging.DEBUG). - The
BatchSpanProcessorexports on a background thread — ensure the process runs long enough for the first flush.
401 Unauthorized
- Check the
Authorizationheader value is"Bearer <token>"(capital B, space before token).
400 Bad Request
- The
X-Scope-OrgIDheader is missing or misspelled.