Agent Skills › getsentry/sentry › backend-conventions

backend-conventions

GitHub

定义Sentry后端日志、追踪、指标和选项系统的编码规范,指导正确添加日志、记录指标、设置标签及读取配置。

.agents/skills/backend-conventions/SKILL.md getsentry/sentry

Trigger Scenarios

添加日志 记录指标 设置属性或标签 读取配置选项

Install

npx skills add getsentry/sentry --skill backend-conventions -g -y
More Options

Non-standard path

npx skills add https://github.com/getsentry/sentry/tree/master/.agents/skills/backend-conventions -g -y

Use without installing

npx skills use getsentry/sentry@backend-conventions

指定 Agent (Claude Code)

npx skills add getsentry/sentry --skill backend-conventions -a claude-code -g -y

安装 repo 全部 skill

npx skills add getsentry/sentry --all -g -y

预览 repo 内 skill

npx skills add getsentry/sentry --list

SKILL.md

Frontmatter
{
    "name": "backend-conventions",
    "description": "Sentry backend conventions for logging, tracing\/spans, span\/tag attribute naming, metrics tags, and the options system. Use when adding or editing Python in src\/ that logs (logger.info\/exception), records metrics (metrics.incr\/timing with tags), instruments spans\/transactions, calls sentry_sdk.set_tag\/set_attribute or set_span_tag\/set_span_data, or reads registered options with options.get(). Trigger on \"add logging\", \"log an error\", \"add a metric\", \"add a span\", \"instrument tracing\", \"set an attribute\", \"add a tag\", \"read an option\", \"LOG005\", \"LOG011\", or metrics tag cardinality questions."
}

Backend Conventions: Logging, Tracing, Metrics, Options

Options System

Sentry uses a centralized options system where all options are registered in src/sentry/options/defaults.py with required default values.

# CORRECT: options.get() without default - registered default is used
from sentry import options

batch_size = options.get("deletions.group-hash-metadata.batch-size")

# WRONG: Redundant default value
batch_size = options.get("deletions.group-hash-metadata.batch-size", 1000)

Important: Never add a default value to options.get() calls. All options are registered via register() in defaults.py which requires a default value. The options system always returns the registered default if no value is set, making a second default parameter redundant and potentially inconsistent.

Logging Pattern

import logging
from sentry import analytics
from sentry.analytics.events.feature_used import FeatureUsedEvent  # does not exist, only for demonstration purposes

logger = logging.getLogger(__name__)

# Structured logging
logger.info(
    "user.action.complete",
    extra={
        "user_id": user.id,
        "action": "login",
        "ip_address": request.META.get("REMOTE_ADDR"),
    }
)

# IMPORTANT: LOG005 use exception() within an exception handler
# WRONG: Calling logger.error() when capturing exception
try:
    risky_operation()
except ValidationError as e:
    logger.error("error.invalid_payload")

# RIGHT: Use logger.exception() with a message when capturing an exception
try:
    risky_operation()
except ValidationError:
    logger.exception("error.invalid_payload")

# IMPORTANT: Avoid LOG011 - Never pre-format log messages with f-strings or .format()
# WRONG: Pre-formatting evaluates before logger call, even if logging is disabled
logger.info(f"User {user.id} completed {action}")
logger.info("User {} completed {}".format(user.id, action))

# RIGHT: Use logger's %-formatting for lazy evaluation
logger.info("%s.user.action.complete", PREFIX)

# ALSO RIGHT: Use structured logging with extra parameters only
logger.info(
    "user.action.complete", extra={"user_id": user.id}
)

# Analytics event
analytics.record(
    FeatureUsedEvent(
        user_id=user.id,
        organization_id=org.id,
        feature="new-dashboard",
    )
)

Span / Tag Attribute Names

Before inventing a key for sentry_sdk.set_tag/set_attribute, set_span_tag, or set_span_data, check whether OTel or Sentry already has a standard name for it in sentry_conventions.attributes.ATTRIBUTE_NAMES. Reusing a convention name keeps the attribute queryable and consistent with what other producers (SDKs, Relay) already emit for the same concept — a bespoke name fragments the same data across two keys.

from sentry_conventions.attributes import ATTRIBUTE_NAMES

# WRONG: inventing a name for a concept the conventions already cover
sentry_sdk.set_attribute("request_user_agent", user_agent)

# RIGHT: use the existing convention name
sentry_sdk.set_attribute(ATTRIBUTE_NAMES.USER_AGENT_ORIGINAL, user_agent)

ATTRIBUTE_NAMES is generated from the OTel semantic conventions plus Sentry's own model (.venv/lib/python*/site-packages/sentry_conventions/attributes.py); grep it for candidate keywords before adding a new one. Only fall back to a custom key when the concept genuinely isn't covered, and prefer a namespaced, descriptive name over a generic one. A key kept behind a _test/POC suffix while a feature is unreleased is a separate, deliberate case — that's about hiding the field, not about picking its name.

Metrics Tags

Every distinct tag-value combination is a separate time series, so keep tags low-cardinality, meaningful, and minimal:

  • Add a tag only if you'll actually filter or group by it. Fewer is better.
  • Tag values must be bounded/enumerable (e.g. status, platform, reason) — never unbounded identifiers (IDs, emails, URLs, free text).

The middleware (src/sentry/metrics/middleware.py) enforces this by denylisting tag keys that end in _id or that are exactly event/project/group. Such tags will not work: they're silently stripped by default, and raise BadMetricTags when SENTRY_METRICS_DISALLOW_BAD_TAGS is on (e.g. CI) — so a metric that looks fine locally can fail elsewhere.

metrics.incr("my.metric", tags={"project_id": project.id})   # WRONG: stripped / raises
metrics.incr("my.metric", tags={"platform": project.platform})  # RIGHT: bounded values

A few keys are allowlisted despite the rule (see _NOT_BAD_TAGS); don't expand it to work around the constraint — pick a low-cardinality tag instead.

Version History

  • 991ee88 Current 2026-09-28 21:58

    移除关于使用追踪shim的建议,明确无条件使用sentry_sdk.traces命名空间下的流式API。

  • 2f300b6 2026-09-23 11:32
  • d3c9056 2026-08-20 20:32

Same Skill Collection

.agents/skills/bump-sentry-dependency/SKILL.md
.agents/skills/cmdk-actions/SKILL.md
.agents/skills/design-system/SKILL.md
.agents/skills/feature-flags/SKILL.md
.agents/skills/frontend-data-fetching/SKILL.md
.agents/skills/generate-frontend-forms/SKILL.md
.agents/skills/generate-migration/SKILL.md
.agents/skills/generate-snapshot-tests/SKILL.md
.agents/skills/hybrid-cloud-rpc/SKILL.md
.agents/skills/hybrid-cloud-test-gen/SKILL.md
.agents/skills/lint-fix/SKILL.md
.agents/skills/lint-new/SKILL.md
.agents/skills/migrate-container-queries/SKILL.md
.agents/skills/migrate-frontend-forms/SKILL.md
.agents/skills/notification-platform/SKILL.md
.agents/skills/react-component-documentation/SKILL.md
.agents/skills/react-testing/SKILL.md
.agents/skills/scraps-review/SKILL.md
.agents/skills/seer-embed/SKILL.md
.agents/skills/sentry-backend-bugs/SKILL.md
.agents/skills/sentry-javascript-bugs/SKILL.md
.agents/skills/sentry-security/SKILL.md
.agents/skills/analytics/SKILL.md
.agents/skills/cell-architecture/SKILL.md
.agents/skills/django-models/SKILL.md
.agents/skills/hybrid-cloud-outboxes/SKILL.md
.agents/skills/migrate-breadcrumb-list/SKILL.md
.agents/skills/remove-option-or-flag/SKILL.md
.agents/skills/setup-dev/SKILL.md

Metadata

Files
0
Version
991ee88
Hash
2ac5ff89
Indexed
2026-08-20 20:32

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-04 07:14
浙ICP备14020137号-1