본문으로 건너뛰기
버전: 0.0.3

Distributed Tracing

Built-in OpenTelemetry tracing for every data operation. Spans follow Database Client Semantic Conventions and export via OTLP gRPC.

Quick Start

pip install aerospike-py            # tracing built-in
pip install aerospike-py[otel] # + context propagation from Python spans
import aerospike_py

# 1. Initialize
aerospike_py.init_tracing()

# 2. Use client -- all operations are traced automatically
client = aerospike_py.client({"hosts": [("127.0.0.1", 3000)]}).connect()
client.put(("test", "users", "user1"), {"name": "Alice"})
client.get(("test", "users", "user1"))
client.close()

# 3. Flush pending spans before exit
aerospike_py.shutdown_tracing()

API

FunctionDescription
init_tracing()Initialize OTLP tracer. Reads OTEL_* env vars.
shutdown_tracing()Flush and shut down. Call before process exit.

Both are thread-safe and idempotent.

Environment Variables

VariableDefaultDescription
OTEL_EXPORTER_OTLP_ENDPOINThttp://localhost:4317OTLP gRPC endpoint
OTEL_SERVICE_NAMEaerospike-pyService name
OTEL_SDK_DISABLEDfalseDisable tracing entirely
OTEL_TRACES_EXPORTERotlpSet to none to disable export

Span Attributes

AttributeExample
db.system.nameaerospike
db.namespacetest
db.collection.nameusers
db.operation.namePUT, GET, REMOVE

Span name: {OPERATION} {namespace}.{set} (e.g., PUT test.users)

On error: error.type, db.response.status_code, otel.status_code=ERROR

Instrumented: put, get, select, exists, remove, touch, append, prepend, increment, operate, batch_read, batch_operate, batch_remove, query

Context Propagation

With aerospike-py[otel] installed, W3C TraceContext is automatically propagated from Python active spans to Rust spans:

SetupBehavior
aerospike-py[otel] + active spanPython span becomes parent
aerospike-py[otel] + no active spanRoot span created
aerospike-py (base)Root span (no propagation)

Framework Integration

FastAPI

from contextlib import asynccontextmanager
import aerospike_py
from fastapi import FastAPI

@asynccontextmanager
async def lifespan(app: FastAPI):
aerospike_py.init_tracing()
client = aerospike_py.AsyncClient({"hosts": [("127.0.0.1", 3000)]})
await client.connect()
app.state.aerospike = client
yield
await client.close()
aerospike_py.shutdown_tracing()

app = FastAPI(lifespan=lifespan)

For end-to-end HTTP-to-Aerospike traces:

pip install opentelemetry-instrumentation-fastapi
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
FastAPIInstrumentor.instrument_app(app)

Django

# apps.py
from django.apps import AppConfig
import aerospike_py

class MyAppConfig(AppConfig):
name = "myapp"
def ready(self):
aerospike_py.init_tracing()

# settings.py
import atexit, aerospike_py
atexit.register(aerospike_py.shutdown_tracing)

Jaeger Setup

docker run -d --name jaeger \
-p 4317:4317 -p 16686:16686 \
jaegertracing/all-in-one:latest

export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_SERVICE_NAME=my-aerospike-app

Visit http://localhost:16686 to view traces.

Disabling Tracing

export OTEL_SDK_DISABLED=true          # disable entirely
export OTEL_TRACES_EXPORTER=none # spans created but not exported

Graceful Degradation

ScenarioBehavior
OTLP endpoint unreachableWarning log, tracing disabled
init_tracing() not calledNo-op spans
opentelemetry-api not installedRoot spans (no propagation)
shutdown_tracing() not calledSome pending spans may be lost

Performance

ScenarioOverhead
Span creation~1-5 us
Context propagation~10-50 us
vs network round-trip< 1%
OTEL_SDK_DISABLED=true~30-80 ns (metrics only)