@superloglabs/otel-python-style

Python OpenTelemetry style: module-scope tracers/meters, decorators for bounded work, error spans, logs, and no wrappers.

View in AI SkillSafe app
Scanned · no findings
0 downloads
0 stars
0 demos
SKILL.md
nameotel-python-style
descriptionPython OpenTelemetry style: module-scope tracers/meters, decorators for bounded work, error spans, logs, and no wrappers.

OTel Python Style

Acquire OTel objects at module scope.

from opentelemetry import metrics, trace
from opentelemetry.trace import Status, StatusCode

tracer = trace.get_tracer("mugline.voice")
meter = metrics.get_meter("mugline.voice")

greetings = meter.create_counter("voice.greetings.delivered", unit="1")

Bounded Work

tracer.start_as_current_span(...) works as both a decorator and a context manager — the same call. For a whole function, the decorator form is usually what you want:

@tracer.start_as_current_span("do_work")
def do_work():
    print("doing some work...")

It works the same way on async functions and on methods, and you can grab the active span inside the body with trace.get_current_span() to set attributes:

@tracer.start_as_current_span("voice.deliver_initial_greeting")
async def _deliver_initial_greeting(*, tenant_id: str, user_id: str) -> None:
    span = trace.get_current_span()
    span.set_attributes({
        "tenant.id": tenant_id,
        "user.id": user_id,
        "voice.use_case": "initial_greeting",
    })

Use a context manager when a decorator does not fit (partial scope, dynamic span name, etc.).

with tracer.start_as_current_span("order.validate") as span:
    span.set_attribute("tenant.id", tenant_id)
    validate_order(order)

Do not use detached tracer.start_span(...); span.end() for bounded work.

Error Paths

Record exceptions on the active span.

try:
    result = await client.messages.create(...)
except Exception as exc:
    span = trace.get_current_span()
    span.record_exception(exc)
    span.set_status(Status(StatusCode.ERROR))
    logger.exception("llm mug copy failed", extra={"tenant_id": tenant_id})
    raise

Logs

If logs are claimed as OTLP-forwarded, configure both:

  • an OTel LoggerProvider + OTLPLogExporter + LoggingHandler
  • set_logger_provider(logger_provider) from opentelemetry._logs
  • log correlation for existing records, e.g. LoggingInstrumentor().instrument(...)

Preserve existing logging.basicConfig, console/file handlers, and log levels.

Init Behavior

Use the source-level public Superlog configuration pattern from otel-onboarding-style in the init module. The public project token is write-only and belongs with the endpoint in the setup block, like a PostHog project token or Sentry DSN.

SUPERLOG_ENDPOINT = "https://intake.superlog.sh"
SUPERLOG_PUBLIC_TOKEN = "sl_public_..."


# The token MUST be sent as the `x-api-key` header. Ingest only reads
# `x-api-key` or `Authorization: Bearer <token>`; any other header name 401s.
def superlog_headers(token: str) -> dict[str, str]:
    return {"x-api-key": token}


def init_observability() -> None:
    exporter = OTLPSpanExporter(
        endpoint=f"{SUPERLOG_ENDPOINT}/v1/traces",
        headers=superlog_headers(SUPERLOG_PUBLIC_TOKEN),
    )
    ...

Add a small _INITIALIZED guard only when the app can realistically call this function more than once.

Metrics

Counters:

  • llm.tokens.input
  • llm.tokens.output
  • requests/events/jobs/errors

Use semantic units when the SDK supports them: token counters use unit="tokens". Do not add app-side llm.cost_usd pricing metrics for normal LLM calls; Superlog estimates cost centrally from provider/model/token data.

Histograms:

  • duration
  • latency
  • payload size

Avoid raw high-cardinality values in metric attributes. Prefer tenant/org/project, operation/use case, provider/model, and outcome dimensions over user-level metric tags.

Embed badges

Add these to your README to show the skill's verification status.

SkillSafe verified badge
Verified badge
[![SkillSafe verified badge](https://api.skillsafe.ai/v1/badge/@superloglabs/otel-python-style/verified)](https://skillsafe.ai/skill/@superloglabs/otel-python-style/)
Installs badge
Installs badge
[![Installs badge](https://api.skillsafe.ai/v1/badge/@superloglabs/otel-python-style/installs)](https://skillsafe.ai/skill/@superloglabs/otel-python-style/)
Scan badge
Scan badge
[![Scan badge](https://api.skillsafe.ai/v1/badge/@superloglabs/otel-python-style/scan)](https://skillsafe.ai/skill/@superloglabs/otel-python-style/)
Eval pass rate badge
Eval pass rate
[![Eval pass rate badge](https://api.skillsafe.ai/v1/badge/@superloglabs/otel-python-style/eval)](https://skillsafe.ai/skill/@superloglabs/otel-python-style/)