エラーが発生したとき、ログに十分な情報がなければ原因の特定に何時間もかかります。逆に、構造化されたログとSentryのエラートラッキングが整備されていれば、Claude CodeのSentry MCPを使って「未解決エラーを取得→スタックトレース分析→修正コード生成→PR作成」まで自動化できます。
この記事では、Pino(構造化ログ)+ Sentry(エラー監視)+ Claude Code(自動トリアージ/修正)の3層構成で、エラー監視とロギングを実践的に構築する方法を解説します。
Sentry MCP ── Claude Codeからエラーを直接分析する
Sentry公式のMCPサーバーを設定すると、Claude CodeからSentryのイシュー取得・イベント分析・プロジェクト管理が直接できるようになります。
# Sentry MCPサーバーを追加(OAuth認証) claude mcp add --transport http sentry https://mcp.sentry.dev/mcp # 組織・プロジェクト限定でスコープを絞る場合 claude mcp add --transport http sentry https://mcp.sentry.dev/mcp/my-org/my-project
設定後、Claude Codeで以下の操作が可能になります:
| MCPツール | できること |
|---|---|
list_project_issues |
プロジェクト内の未解決イシュー一覧を取得 |
get_sentry_issue |
特定イシューの詳細(スタックトレース・影響ユーザー数等)を取得 |
get_sentry_event |
個別のエラーイベントの詳細を取得 |
resolve_short_id |
ショートID(PROJECT-123)からイシュー詳細を取得 |
list_error_events_in_project |
直近のエラーイベント一覧を取得 |
create_project |
Sentryプロジェクトの新規作成 |
# Claude Codeのプロンプトで > 未解決のエラーイシューを優先度順に5件取得して、 > 各エラーのスタックトレースを分析し、修正方法を提案してください > PROJECT-456 のエラーを分析して、根本原因を特定し修正コードを生成してください > 過去24時間に発生したエラーイベントの傾向を分析して、 > 最も影響が大きいエラーから順に対応方針を提案してください
MCPの詳しい設定方法はClaude Code MCP完全ガイドをご覧ください。
Sentry SDK v10 ── Next.jsへの導入
Sentry SDK v10 を Next.js 16 プロジェクトに導入してください。 要件: - instrumentation-client.ts(クライアントSDK初期化) - sentry.server.config.ts(サーバーSDK初期化) - next.config.ts にwithSentryConfig設定 - Source Maps自動アップロード - トンネルルート(/monitoring)でアドブロッカー回避 - Session Replay(エラー時100%、通常時10%) - Pino統合(pinoIntegration) - 開発時はtracesSampleRate: 1.0、本番は0.1
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
sendDefaultPii: true,
// パフォーマンス監視
tracesSampleRate: process.env.NODE_ENV === "development" ? 1.0 : 0.1,
// Session Replay
integrations: [
Sentry.replayIntegration(),
Sentry.feedbackIntegration({ colorScheme: "system" }),
],
replaysSessionSampleRate: 0.1, // 通常セッション: 10%
replaysOnErrorSampleRate: 1.0, // エラー時: 100%
enableLogs: true,
});
// Next.js 15以降 + Sentry SDK 9.12.0以降: ルーター遷移のキャプチャ
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
import { withSentryConfig } from "@sentry/nextjs";
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// ... 既存の設定
};
export default withSentryConfig(nextConfig, {
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
silent: !process.env.CI,
widenClientFileUpload: true,
tunnelRoute: "/monitoring", // アドブロッカー回避
});
tunnelRoute: "/monitoring"を設定すると、Sentryへのリクエストが自分のドメイン経由になるため、広告ブロッカーにブロックされません。本番環境では必須の設定です。Pino ── 構造化ログの設計
PinoはNode.js最速のロガーで、JSON形式の構造化ログを出力します。requestIdやuserIdを全ログに自動付与することで、エラー発生時のデバッグが格段に楽になります。
Pinoで構造化ログを設定してください。 要件: - 開発時: pino-pretty(カラー出力) - 本番: JSON出力 - requestId/traceIdを全ログに自動付与(AsyncLocalStorage) - パスワード・トークン等の機密情報をredactで除外 - error()にはErrorオブジェクトを第1引数で渡す - Sentry pinoIntegrationと連携
import pino from "pino";
const logger = pino({
level: process.env.LOG_LEVEL || "info",
formatters: {
level: (label) => ({ level: label.toUpperCase() }),
},
timestamp: pino.stdTimeFunctions.isoTime,
// 機密情報を自動除外
redact: {
paths: ["req.headers.authorization", "password", "token", "secret"],
remove: true,
},
// 開発時はpino-prettyでカラー出力
transport:
process.env.NODE_ENV === "development"
? { target: "pino-pretty", options: { colorize: true } }
: undefined,
});
export default logger;
import { AsyncLocalStorage } from "node:async_hooks";
import pino from "pino";
import baseLogger from "./logger";
interface RequestContext {
requestId: string;
userId?: string;
logger: pino.Logger;
}
export const asyncLocalStorage = new AsyncLocalStorage<RequestContext>();
// ミドルウェアで各リクエストにコンテキストを設定
export function requestContextMiddleware(req: any, res: any, next: () => void) {
const requestId = (req.headers["x-request-id"] as string) || crypto.randomUUID();
const childLogger = baseLogger.child({ requestId });
const context: RequestContext = {
requestId,
logger: childLogger,
};
asyncLocalStorage.run(context, next);
}
// どこからでもリクエストスコープのロガーを取得
export function getLogger(): pino.Logger {
const store = asyncLocalStorage.getStore();
return store?.logger || baseLogger;
}
import { getLogger } from "@/lib/context";
async function processOrder(orderId: string) {
const logger = getLogger();
logger.info({ orderId }, "注文処理を開始");
try {
const result = await db.orders.process(orderId);
logger.info({ orderId, result: result.status }, "注文処理が完了");
return result;
} catch (error) {
// Error オブジェクトを第1引数に渡す(Pinoのベストプラクティス)
logger.error(error, "注文処理でエラーが発生");
throw error;
}
}
logger.error()は第1引数にErrorオブジェクトを渡すのが正しい使い方です。logger.error(error.message)とするとスタックトレースが失われます。CLAUDE.mdに明記しておきましょう。Sentry × Pino統合 ── ログをSentryに自動転送する
Sentry SDK v10のpinoIntegrationを使うと、Pinoのログが自動的にSentryのLogsに転送されます。pinoIntegrationはNode.jsランタイム専用のため、sentry.server.config.ts(サーバー側)で設定します。
import * as Sentry from "@sentry/node";
Sentry.init({
dsn: process.env.SENTRY_DSN,
enableLogs: true,
integrations: [
Sentry.pinoIntegration({
// SentryのLogsに転送するレベル
log: { levels: ["info", "warn", "error", "fatal"] },
// SentryのErrorsとして報告するレベル
error: { levels: ["error", "fatal"] },
}),
],
});
logger.error()で記録したログはSentryのErrorsとLogsの両方に表示されます。エラーのコンテキスト(requestId、userId等)がSentry上でも確認できるため、デバッグ効率が大幅に向上します。Claude Codeでエラーを自動トリアージ・修正する
Sentry MCPと組み合わせると、Claude Codeが未解決エラーを定期的に分析し、修正PRを自動作成するワークフローを構築できます。
Sentry MCPを使って以下を実行してください: 1. list_project_issues で未解決のエラーイシューを取得(直近7日間) 2. 影響ユーザー数が多い順にソート 3. 上位3件について: a. get_sentry_issue でスタックトレースを取得 b. 該当するソースコードを読んで根本原因を特定 c. 修正コードを生成 d. テストを追加 4. 修正をコミットしてPRを作成
name: Sentry Error Triage
on:
schedule:
- cron: "0 0 * * 1" # 毎週月曜9:00 JST
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
direct_prompt: |
Sentry MCPを使って未解決エラーを分析し修正PRを作成してください。
1. list_project_issues で未解決イシューを取得
2. 影響の大きい上位3件のスタックトレースを取得
3. 根本原因を分析し修正コードを生成
4. テストを追加してPRを作成(最大2件)
mcp_config: |
{
"mcpServers": {
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp"
}
}
}
CLAUDE.mdにエラー処理・ロギングルールを記述する
## エラー処理・ロギングルール ### ロギング - ロガー: Pino(構造化JSON出力) - logger.error(error, "メッセージ") 形式を厳守(error.messageだけを渡さない) - 全ログにrequestId/traceIdを含める(AsyncLocalStorage経由) - 機密情報(password/token/secret)はredactで自動除外 - 開発時: pino-pretty、本番: JSON出力 ### エラーハンドリング - try-catchでエラーを握りつぶさない(必ずログ出力またはrethrow) - API境界では Sentry.captureException() でSentryに送信 - ユーザー向けエラーメッセージに内部情報を含めない - 予期しないエラーは500 + 汎用メッセージ、予期されたエラーは適切なHTTPステータス ### Sentry連携 - 全エラーに requestId / userId をSentry tagとして付与 - tracesSampleRate: 開発1.0、本番0.1 - Session Replay: エラー時100%、通常時10% - tunnelRoute: "/monitoring" でアドブロッカー回避
よくある質問
AsyncLocalStorageを使います。ミドルウェアでリクエスト受信時にcrypto.randomUUID()で生成し、asyncLocalStorage.run(context, next)で伝搬させます。以降のすべての関数呼び出しでgetLogger()を使えば、requestIdが自動的にログに付与されます。レスポンスヘッダー(X-Request-Id)にも返すとフロントエンドとの紐付けも容易になります。まとめ
- Sentry MCP: Claude Codeから直接エラーイシューを取得・分析。自動トリアージ+修正PRのワークフローが構築可能
- Sentry SDK v10: Next.jsへの導入。tunnelRouteでアドブロッカー回避、Session Replayでエラー再現
- Pino構造化ログ: requestId/traceIdの自動付与(AsyncLocalStorage)、機密情報のredact、pino-prettyでの開発体験
- Sentry × Pino統合: pinoIntegrationでログをSentryに自動転送。エラーのコンテキストがSentry上で確認可能
- 自動トリアージ: GitHub Actionsの週次スケジュールでClaude Codeが未解決エラーを分析し修正PRを自動作成
- CLAUDE.md: logger.error(error, msg)形式の強制、requestId必須、redactルールを明記して品質を担保
デバッグ全般はClaude Codeデバッグ完全ガイド、テスト戦略はClaude Codeテスト完全ガイド、OpenTelemetry連携はClaude Code × OpenTelemetry完全ガイドもあわせてご覧ください。
