mcpField
O
otel-python-style

otel-python-style

github.com/superloglabs开发13377 次安装21 周前更新
代码仓库

关于 otel-python-style

面向 Python 开发者的 OpenTelemetry 编码规范技能,涵盖追踪、错误、日志、初始化和指标,帮助应用按统一方式实现可观测性。

主要功能

  1. 01模块级追踪与指标对象
  2. 02装饰器和上下文管理器跨度
  3. 03异常记录与状态设置
  4. 04OTLP 日志配置指引
  5. 05指标命名与基数控制指引

适用场景

  1. 01为同步或异步任务添加追踪
  2. 02在活动跨度中记录异常
  3. 03配置日志的 OTLP 转发
  4. 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.input
  • llm.tokens.output
  • 请求/事件/任务/错误

在 SDK 支持时使用语义单位:令牌计数器使用 unit="tokens"。对于常规的大模型调用,不要添加应用侧的 llm.cost_usd 定价指标;Superlog 会根据提供商/模型/令牌数据集中估算成本。

直方图:

  • 持续时间
  • 延迟
  • 负载大小

避免在指标属性中使用原始高基数值。与用户级指标标签相比,优先使用租户/组织/项目、操作/用例、提供商/模型和结果维度。

评论

支持 Markdown