Lightstep (OpenTracing - Deprecated)
The `lightstep` library provides the Python OpenTracing implementation for sending tracing data to Lightstep (now ServiceNow Cloud Observability). As of late 2020, Lightstep strongly recommends migrating to OpenTelemetry for all new and existing Python instrumentation, and this `lightstep-tracer-python` library is no longer the recommended approach. The current version is 4.4.8, but new development has shifted to OpenTelemetry-based solutions.
Common errors
-
ModuleNotFoundError: No module named 'opentracing'
cause The deprecated `lightstep` library explicitly depends on the `opentracing` package.fixIf you intend to use the legacy `lightstep` tracer, ensure `pip install opentracing` is run. Otherwise, migrate to OpenTelemetry which has its own APIs and does not directly use `opentracing`. -
grpc._channel._MultiThreadedRendezvous: <_MultiThreadedRendezvous of RPC that terminated with: status = StatusCode.UNAVAILABLE details = "failed to connect to all addresses" debug_error_string = ""
cause This typically indicates a gRPC connectivity issue, such as an incorrect endpoint, firewall blockage, or network problem preventing the OpenTelemetry OTLP exporter from reaching the Lightstep ingest endpoint.fixVerify that `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` is correctly set (e.g., `ingest.lightstep.com:443` or `ingest.eu.lightstep.com:443`). Check network connectivity and firewall rules. Ensure TLS is configured correctly or use `insecure=True` if connecting to a local Collector without TLS (not recommended for production). Set gRPC debug environment variables for more details (e.g., `GRPC_TRACE=all GRPC_VERBOSITY=DEBUG`). -
ValueError: Lightstep access token is required.
cause The OpenTracing-based Lightstep tracer requires an access token, which was often passed during `lightstep.Tracer` initialization. The OpenTelemetry exporter requires it via `lightstep-access-token` header.fixFor OpenTracing: Pass `access_token='YOUR_ACCESS_TOKEN'` during `lightstep.Tracer` initialization. For OpenTelemetry: Set the `LS_ACCESS_TOKEN` environment variable or explicitly provide the `lightstep-access-token` header to the OTLP exporter as shown in the quickstart. Ensure the token is valid for your Lightstep/Cloud Observability project.
Warnings
- breaking The direct `lightstep-tracer-python` library is officially deprecated in favor of OpenTelemetry. Existing applications using `lightstep.Tracer` directly will not receive new features or bug fixes, and users are strongly advised to migrate.
- deprecated The `lightstep` PyPI package, which provides the `lightstep-tracer-python` OpenTracing implementation, is deprecated. Lightstep (now ServiceNow Cloud Observability) has fully embraced OpenTelemetry.
- gotcha Installing multiple versions of OpenTelemetry packages, or older Lightstep tracers alongside OpenTelemetry, can cause traces not to be created or propagated correctly due to conflicts.
- gotcha When using `opentelemetry-bootstrap -a install` on slim Linux distributions (e.g., CentOS), you might encounter issues due to missing `gcc` and `gcc-c++` compilers.
Install
-
pip install lightstep -
pip install opentelemetry-distro opentelemetry-exporter-otlp opentelemetry-bootstrap -a install
Imports
- Tracer
from lightstep import Tracer # direct import often leads to issues with global tracer registration
import lightstep opentracing.tracer = lightstep.Tracer(...)
- trace
from opentelemetry import trace
Quickstart
import os
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
# --- Configuration (using environment variables for security) ---
LS_ACCESS_TOKEN = os.environ.get('LS_ACCESS_TOKEN', 'YOUR_LIGHTSTEP_ACCESS_TOKEN')
SERVICE_NAME = os.environ.get('OTEL_SERVICE_NAME', 'my-python-app')
OTLP_ENDPOINT = os.environ.get('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'ingest.lightstep.com:443')
# Configure resource
resource = Resource.create({"service.name": SERVICE_NAME})
# Configure tracer provider
provider = TracerProvider(resource=resource)
# Configure OTLP exporter for Lightstep
otlp_exporter = OTLPSpanExporter(
endpoint=OTLP_ENDPOINT,
headers={
"lightstep-access-token": LS_ACCESS_TOKEN
},
# Optionally, if using a collector without TLS, set insecure=True
# insecure=True
)
# Configure console exporter for local debugging
console_exporter = ConsoleSpanExporter()
# Add span processors
provider.add_span_processor(SimpleSpanProcessor(otlp_exporter))
provider.add_span_processor(SimpleSpanProcessor(console_exporter))
# Set the global tracer provider
trace.set_tracer_provider(provider)
# Acquire a tracer
tracer = trace.get_tracer(__name__)
def my_function():
with tracer.start_as_current_span("my_function_span") as span:
span.set_attribute("event", "example")
print("Executing my_function")
nested_function()
def nested_function():
with tracer.start_as_current_span("nested_function_span"):
print("Executing nested_function")
if __name__ == "__main__":
print(f"Sending traces for service: {SERVICE_NAME} to {OTLP_ENDPOINT}")
my_function()
# It's important to shut down the tracer provider to ensure all spans are flushed
provider.shutdown()