关于 otel-python-style
面向 Python 开发者的 OpenTelemetry 编码规范技能,涵盖追踪、错误、日志、初始化和指标,帮助应用按统一方式实现可观测性。
主要功能
- 01模块级追踪与指标对象
- 02装饰器和上下文管理器跨度
- 03异常记录与状态设置
- 04OTLP 日志配置指引
- 05指标命名与基数控制指引
适用场景
- 01为同步或异步任务添加追踪
- 02在活动跨度中记录异常
- 03配置日志的 OTLP 转发
- 04跟踪 LLM 令牌与请求指标
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ superloglabs/ skills --skill otel-python-style安装后在 Claude Code 中输入/otel-python-style确认已加载。
详细介绍
OTel Python 风格
在模块级别获取 OTel 对象。
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")
有界工作
tracer.start_as_current_span(...) 既可以用作装饰器,也可以用作上下文管理器——调用方式相同。对于整个函数,通常建议使用装饰器形式:
@tracer.start_as_current_span("do_work")
def do_work():
print("doing some work...")
它对异步函数和方法同样适用,你还可以在函数体内使用 trace.get_current_span() 获取当前活动 span 并设置属性:
@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",
})
装饰器不适用时(例如只需覆盖部分范围、span 名称是动态的等),请使用上下文管理器。
with tracer.start_as_current_span("order.validate") as span:
span.set_attribute("tenant.id", tenant_id)
validate_order(order)
对于有界工作,不要使用分离的 tracer.start_span(...); span.end()。
错误路径
在活动 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
日志
如果声称日志会转发到 OTLP,请同时配置:
- OTel LoggerProvider + OTLPLogExporter + LoggingHandler
- 从
opentelemetry._logs导入的set_logger_provider(logger_provider) - 为现有日志记录添加日志关联,例如
LoggingInstrumentor().instrument(...)
保留现有的 logging.basicConfig、控制台/文件处理器以及日志级别。
初始化行为
在 init 模块中使用 otel-onboarding-style 中源代码级的公开 Superlog 配置模式。公开项目令牌是只写的,应与端点一起放在设置代码块中,就像 PostHog 项目令牌或 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),
)
...
只有在应用确实可能多次调用此函数时,才添加一个简单的 _INITIALIZED 守卫。
指标
计数器:
llm.tokens.inputllm.tokens.output- 请求/事件/任务/错误
在 SDK 支持时使用语义单位:令牌计数器使用 unit="tokens"。对于常规的大模型调用,不要添加应用侧的 llm.cost_usd 定价指标;Superlog 会根据提供商/模型/令牌数据集中估算成本。
直方图:
- 持续时间
- 延迟
- 负载大小
避免在指标属性中使用原始高基数值。与用户级指标标签相比,优先使用租户/组织/项目、操作/用例、提供商/模型和结果维度。