sentry-skill について
sentry-skillは、エラー監視、パフォーマンス追跡、アプリケーション可観測性にSentryを使うための実用ガイドです。監視やリリースを担当する開発者・運用担当者向けに、SDK、CLI、API、アラート、セルフホストを扱います。
主な機能
- 01SDK設定とエラー捕捉
- 02トランザクション、Span、分散呼び出しの追跡
- 03CLIによるリリースとSource Map管理
- 04APIによるイベントとIssueの検索
- 05エラーおよびメトリクスアラート設定
- 06セルフホストとスケーリング対応
活用シーン
- 01アプリケーションエラーと関連イベントの調査
- 02リクエスト性能とサービス間トレースの監視
- 03リリース時のSource Mapアップロード
- 04Issueの検索とアラート設定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ julianobarbosa/ claude-code-skills --skill sentry-skillインストール後、Claude Code で/sentry-skillを入力して読み込まれたか確認します。
詳細
Sentry スキル
Sentry を使用したエラー監視、パフォーマンス追跡、アプリケーションの可観測性に関する包括的なガイドです。
クイックリファレンス
DSN(データソース名)
DSN は、Sentry プロジェクトを一意に識別する名前です。
https://<PUBLIC_KEY>@<HOST>/<PROJECT_ID>
例:https://[email protected]/1234567
基本概念
| 概念 | 説明 |
|---|---|
| イベント | Sentry に送信されるデータの単一インスタンス(エラー、トランザクションなど) |
| イシュー | フィンガープリントによって重複排除された、類似イベントのグループ |
| トランザクション | 作業単位を表す、パフォーマンス監視のスパン |
| スパン | トランザクション内の個別の操作(DB クエリ、HTTP 呼び出し) |
| トレース | サービス間で接続された一連のトランザクション |
| リリース | 環境にデプロイされたコードのバージョン |
| 環境 | デプロイ先(本番、ステージング、開発) |
SDK のインストールと設定
JavaScript/Node.js
npm install @sentry/node @sentry/profiling-node
const Sentry = require("@sentry/node");
const { nodeProfilingIntegration } = require("@sentry/profiling-node");
Sentry.init({
dsn: "https://[email protected]/1",
release: process.env.RELEASE_VERSION || "1.0.0",
environment: process.env.NODE_ENV || "development",
// Error sampling (1.0 = 100% of errors)
sampleRate: 1.0,
// Performance monitoring (0.1 = 10% of transactions)
tracesSampleRate: 0.1,
// OR use dynamic sampling
tracesSampler: (samplingContext) => {
if (samplingContext.transactionContext.name === "/health") {
return 0; // Don't sample health checks
}
if (samplingContext.parentSampled !== undefined) {
return samplingContext.parentSampled; // Inherit parent decision
}
return 0.1; // Default 10%
},
// Profiling
profilesSampleRate: 0.1,
integrations: [nodeProfilingIntegration()],
// Data scrubbing
beforeSend(event) {
if (event.request?.headers) {
delete event.request.headers["Authorization"];
}
return event;
},
});
Python
pip install sentry-sdk
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
sentry_sdk.init(
dsn="https://[email protected]/1",
release="[email protected]",
environment="production",
# Error sampling
sample_rate=1.0,
# Performance monitoring
traces_sample_rate=0.1,
# OR dynamic sampling
traces_sampler=lambda ctx: (
0 if ctx.get("transaction_context", {}).get("name") == "/health"
else 0.1
),
# Profiling
profiles_sample_rate=0.1,
# Integrations
integrations=[
FlaskIntegration(),
SqlalchemyIntegration(),
],
# Data scrubbing
before_send=lambda event, hint: scrub_sensitive_data(event),
)
def scrub_sensitive_data(event):
if event.get("request", {}).get("headers"):
event["request"]["headers"].pop("Authorization", None)
return event
Go
go get github.com/getsentry/sentry-go
package main
import (
"log"
"time"
"github.com/getsentry/sentry-go"
)
func main() {
err := sentry.Init(sentry.ClientOptions{
Dsn: "https://[email protected]/1",
Release: "[email protected]",
Environment: "production",
TracesSampleRate: 0.1,
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
// Scrub sensitive data
return event
},
})
if err != nil {
log.Fatalf("sentry.Init: %s", err)
}
defer sentry.Flush(2 * time.Second)
}
エラーのキャプチャ
エラーの手動キャプチャ
// JavaScript
try {
riskyOperation();
} catch (error) {
Sentry.captureException(error, {
tags: { component: "payment" },
extra: { orderId: "12345" },
user: { id: "user-123", email: "[email protected]" },
});
}
// Capture message
Sentry.captureMessage("Something unexpected happened", "warning");
# Python
try:
risky_operation()
except Exception as e:
sentry_sdk.capture_exception(e)
sentry_sdk.set_tag("component", "payment")
sentry_sdk.set_extra("order_id", "12345")
sentry_sdk.set_user({"id": "user-123", "email": "[email protected]"})
# Capture message
sentry_sdk.capture_message("Something unexpected happened", level="warning")
ブレッドクラム
// Add context breadcrumbs
Sentry.addBreadcrumb({
category: "auth",
message: "User logged in",
level: "info",
data: { userId: "123" },
});
スコープ
// Configure scope for context
Sentry.configureScope((scope) => {
scope.setUser({ id: "user-123" });
scope.setTag("page_locale", "en-US");
scope.setExtra("session_data", { cart_items: 5 });
});
// Isolated scope
Sentry.withScope((scope) => {
scope.setTag("isolated", "true");
Sentry.captureException(new Error("Scoped error"));
});
パフォーマンス監視
トランザクションの手動作成
const transaction = Sentry.startTransaction({
op: "task",
name: "Process Order",
});
// Set transaction on scope
Sentry.getCurrentHub().configureScope((scope) => {
scope.setSpan(transaction);
});
// Create child spans
const span = transaction.startChild({
op: "db.query",
description: "SELECT * FROM orders",
});
// Do work...
await queryDatabase();
span.finish();
transaction.finish();
分散トレーシング
// Service A - Create trace
const transaction = Sentry.startTransaction({ name: "API Request" });
const traceHeader = transaction.toTraceparent();
// Pass traceHeader to Service B via HTTP header: sentry-trace
// Service B - Continue trace
const incomingTrace = request.headers["sentry-trace"];
const transaction = Sentry.startTransaction({
name: "Process Request",
op: "http.server",
}, { parentSampled: true });
Sentry CLI
インストール
# npm
npm install -g @sentry/cli
# curl
curl -sL https://sentry.io/get-cli/ | bash
# Homebrew
brew install getsentry/tools/sentry-cli
認証
# Login interactively
sentry-cli login
# Or set auth token
export SENTRY_AUTH_TOKEN=your-token
export SENTRY_ORG=your-org
export SENTRY_PROJECT=your-project
リリース管理
# Create release
sentry-cli releases new v1.0.0
# Associate commits (auto-detect from git)
sentry-cli releases set-commits v1.0.0 --auto
# Or specify commit range
sentry-cli releases set-commits v1.0.0 --commit "repo@from_sha..to_sha"
# Upload source maps
sentry-cli releases files v1.0.0 upload-sourcemaps ./dist \
--url-prefix '~/static/js' \
--rewrite
# Upload debug symbols (iOS/Android/Native)
sentry-cli debug-files upload --include-sources path/to/symbols
# Deploy release to environment
sentry-cli releases deploys v1.0.0 new -e production
# Finalize release
sentry-cli releases finalize v1.0.0
ソースマップのワークフロー
# Build with source maps
npm run build
# Create release and upload
export VERSION=$(sentry-cli releases propose-version)
sentry-cli releases new $VERSION
sentry-cli releases files $VERSION upload-sourcemaps ./dist \
--url-prefix '~/' \
--validate
sentry-cli releases finalize $VERSION
Cron の監視
# Wrap a cron job
sentry-cli monitors run <monitor-slug> -- /path/to/script.sh
# Or use check-in API
sentry-cli monitors run <monitor-slug> --check-in-status in_progress
# ... run job ...
sentry-cli monitors run <monitor-slug> --check-in-status ok
テストイベントの送信
sentry-cli send-event -m "Test event from CLI"
API リファレンス
認証
# Bearer token (recommended)
curl -H "Authorization: Bearer <AUTH_TOKEN>" \
https://sentry.io/api/0/projects/
# DSN-based (limited endpoints)
curl -u <PUBLIC_KEY>: \
https://sentry.io/api/<PROJECT_ID>/store/
一般的なエンドポイント
| エンドポイント | メソッド | 説明 |
|---|---|---|
/api/0/organizations/ | GET | 組織の一覧を取得 |
/api/0/organizations/{org}/projects/ | GET | プロジェクトの一覧を取得 |
/api/0/projects/{org}/{project}/issues/ | GET | イシューの一覧を取得 |
/api/0/organizations/{org}/issues/{issue_id}/ | GET | イシューの詳細を取得 |
/api/0/projects/{org}/{project}/events/ | GET | イベントの一覧を取得 |
/api/0/organizations/{org}/releases/ | GET/POST | リリースの一覧取得/作成 |
/api/0/projects/{org}/{project}/keys/ | GET | DSN キーの一覧を取得 |
イシューの検索
# List issues with filters
curl -H "Authorization: Bearer $TOKEN" \
"https://sentry.io/api/0/projects/{org}/{project}/issues/?query=is:unresolved+level:error&statsPeriod=24h"
# Get issue details
curl -H "Authorization: Bearer $TOKEN" \
"https://sentry.io/api/0/organizations/{org}/issues/{issue_id}/"
# Resolve issue
curl -X PUT -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "resolved"}' \
"https://sentry.io/api/0/organizations/{org}/issues/{issue_id}/"
API 経由でのリリース作成
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"version": "v1.0.0",
"projects": ["my-project"],
"refs": [{
"repository": "org/repo",
"commit": "abc123"
}]
}' \
"https://sentry.io/api/0/organizations/{org}/releases/"
ページネーション
# Response includes Link header
Link: <https://sentry.io/api/0/...?cursor=123:0:0>; rel="previous"; results="false",
<https://sentry.io/api/0/...?cursor=456:0:0>; rel="next"; results="true"
レート制限
- デフォルト:ほとんどのエンドポイントで毎秒 40 リクエスト
- 一括処理エンドポイント:より低い制限
- ヘッダー:
X-Sentry-Rate-Limit-Remaining、X-Sentry-Rate-Limit-Reset
アラートの設定
イシューアラート(UI/API 経由)
{
"name": "High Error Rate Alert",
"conditions": [
{
"id": "sentry.rules.conditions.event_frequency.EventFrequencyCondition",
"interval": "1h",
"value": 100
}
],
"actions": [
{
"id": "sentry.integrations.slack.notify_action.SlackNotifyServiceAction",
"channel": "#alerts",
"workspace": "workspace-id"
}
],
"actionMatch": "all",
"filterMatch": "all",
"frequency": 30
}
メトリックアラート
# Example: Alert on error rate > 5%
triggers:
- alertThreshold: 5
label: critical
actions:
- type: slack
channel: "#critical-alerts"
- alertThreshold: 2
label: warning
actions:
- type: email
targetIdentifier: "[email protected]"
OpenTelemetry との統合
Sentry への OTLP エクスポーター
const { NodeSDK } = require("@opentelemetry/sdk-node");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: "https://sentry.io/api/<PROJECT_ID>/envelope/",
headers: {
"sentry-trace": "...",
},
}),
});
sdk.start();
OpenTelemetry と Sentry の併用
const Sentry = require("@sentry/node");
Sentry.init({
dsn: "...",
instrumenter: "otel", // Use OpenTelemetry for instrumentation
tracesSampleRate: 0.1,
});
セルフホスト型デプロイ
システム要件
| リソース | 最小要件 | 推奨 |
|---|---|---|
| CPU | 4 コア | 8 コア以上 |
| RAM | 16 GB | 32 GB 以上 |
| スワップ | 16 GB | - |
| ディスク | 100 GB SSD | 500 GB 以上の SSD |
| Docker | 19.03+ | 最新 |
| Docker Compose | 2.19+ | 最新 |
インストール
# Clone repository
VERSION=$(curl -Ls -o /dev/null -w %{url_effective} \
https://github.com/getsentry/self-hosted/releases/latest)
VERSION=${VERSION##*/}
git clone https://github.com/getsentry/self-hosted.git
cd self-hosted
git checkout ${VERSION}
# Run installer
./install.sh
# Start services
docker compose up -d
# Access at http://localhost:9000
設定(sentry/config.yml)
# Mail
mail.backend: 'smtp'
mail.host: 'smtp.example.com'
mail.port: 587
mail.username: '[email protected]'
mail.password: 'password'
mail.use-tls: true
mail.from: '[email protected]'
# System
system.url-prefix: 'https://sentry.example.com'
system.secret-key: 'your-secret-key'
# Features
features.organizations:early-adopter: False
外部ストレージ(GCS/S3)
# sentry/config.yml
filestore.backend: 'gcs'
filestore.options:
bucket_name: 'sentry-files'
# Or S3
filestore.backend: 's3'
filestore.options:
access_key: 'AWS_ACCESS_KEY'
secret_key: 'AWS_SECRET_KEY'
bucket_name: 'sentry-files'
region_name: 'us-east-1'
外部データベース
# PostgreSQL
SENTRY_POSTGRES_HOST: 'postgres.example.com'
SENTRY_POSTGRES_PORT: '5432'
SENTRY_DB_NAME: 'sentry'
SENTRY_DB_USER: 'sentry'
SENTRY_DB_PASSWORD: 'password'
# Redis
SENTRY_REDIS_HOST: 'redis.example.com'
SENTRY_REDIS_PORT: '6379'
# Kafka
SENTRY_KAFKA_HOST: 'kafka.example.com:9092'
ワーカーのスケーリング
# Scale specific services
docker compose up -d --scale worker=4 --scale snuba-consumer=2
セルフホスト環境の監視
# Enable StatsD metrics
SENTRY_METRICS_BACKEND: 'statsd'
SENTRY_METRICS_OPTIONS:
host: 'statsd.example.com'
port: 8125
ベストプラクティス
サンプリング戦略
// Dynamic sampling based on context
tracesSampler: (ctx) => {
// Always sample errors
if (ctx.transactionContext.name.includes("error")) return 1.0;
// Lower rate for high-volume endpoints
if (ctx.transactionContext.name === "/api/health") return 0;
if (ctx.transactionContext.name.startsWith("/api/v1/")) return 0.05;
// Default rate
return 0.1;
}
データのサニタイズ
beforeSend(event) {
// Remove PII
if (event.user) {
delete event.user.email;
delete event.user.ip_address;
}
// Scrub sensitive headers
if (event.request?.headers) {
delete event.request.headers["Authorization"];
delete event.request.headers["Cookie"];
}
// Filter local errors in production
if (event.exception?.values?.[0]?.type === "ChunkLoadError") {
return null; // Drop event
}
return event;
}
リリースの追跡
# CI/CD Pipeline Example
export SENTRY_RELEASE=$(git rev-parse --short HEAD)
# Before deploy
sentry-cli releases new $SENTRY_RELEASE
sentry-cli releases set-commits $SENTRY_RELEASE --auto
sentry-cli releases files $SENTRY_RELEASE upload-sourcemaps ./dist
# After deploy
sentry-cli releases deploys $SENTRY_RELEASE new -e production
sentry-cli releases finalize $SENTRY_RELEASE
クォータ管理
// Client-side rate limiting
Sentry.init({
dsn: "...",
maxBreadcrumbs: 50,
maxValueLength: 1000,
// Limit events per session
beforeSend(event, hint) {
if (sessionEventCount++ > 100) {
return null; // Drop after 100 events
}
return event;
}
});
よくある操作
統合の問題をデバッグする
# Enable debug mode
Sentry.init({ debug: true });
# Test event delivery
sentry-cli send-event -m "Test message"
# Verify source maps
sentry-cli releases files <release> list
sentry-cli sourcemaps explain <event-id>
イシューを一括で解決する
# Via API
curl -X PUT -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "resolved"}' \
"https://sentry.io/api/0/projects/{org}/{project}/issues/?id=123&id=456"
イベントをエクスポートする
# Query events via Discover
curl -H "Authorization: Bearer $TOKEN" \
"https://sentry.io/api/0/organizations/{org}/events/?field=title&field=count()&query=event.type:error&statsPeriod=7d"
トラブルシューティング
| 問題 | 解決策 |
|---|---|
| イベントが表示されない | DSN を確認し、ネットワーク接続を検証して、debug: true を有効にします |
| ソースマップが機能しない | リリースが一致していることを確認し、URL プレフィックスを確認して、sourcemaps explain を使用します |
| イベント数が多すぎる | サンプリングを実装し、beforeSend を使用してフィルタリングします |
| パフォーマンスへの影響 | tracesSampleRate を下げ、不要な統合を無効にします |
| セルフホスト環境での OOM | メモリを増やし、スワップを追加して、水平スケーリングします |
Reference Documentation
- SDK Configuration: Detailed SDK options
- CLI Commands: Complete CLI reference
- API Endpoints: Full API documentation
- Self-Hosting: Deployment guide
- Alerting: Alert configuration patterns
コメント
Markdown 対応