analyze-logs について
ローカルに保存された evlog のワイドイベントログを分析し、アプリの挙動を調べるスキルです。CLI またはログファイルを使い、エラー、遅いリクエスト、履歴、パターンを確認できます。
主な機能
- 01evlog CLI によるログ検索
- 02時間、ステータス、パス、フィールドで絞り込み
- 03エラーと遅いリクエストの調査
- 04リクエスト ID によるイベント追跡
- 05ファイルシステムとメモリログの読み取り
活用シーン
- 01最近発生したアプリのエラー調査
- 02遅いエンドポイントやリクエストの特定
- 03リクエスト ID に紐づく動作の確認
- 04ルートごとのエラーパターン比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ evloghq/ evlog --skill analyze-logsインストール後、Claude Code で/analyze-logsを入力して読み込まれたか確認します。
詳細
アプリケーションログを分析する
ローカルの .evlog/logs/ ディレクトリから構造化されたワイドイベントログを読み取り、分析して、エラーのデバッグ、パフォーマンスの問題の調査、アプリケーションの動作の把握を行います。
使用するタイミング
- ユーザーがエラーのデバッグ、バグの調査、または問題が発生した原因の把握を求めている
- ユーザーがリクエストのパターン、遅いエンドポイント、またはエラー率について尋ねている
- ユーザーがアプリケーションについて「何が起きたのか」や「何が起きているのか」と尋ねている
- ユーザーがログの分析、最近のエラーの確認、またはアプリケーションの動作の確認を求めている
- ユーザーが表示されている特定のエラーメッセージやステータスコードに言及している
ログの場所を確認する
まず CLI を試してください。どちらのファイル構成も読み取り、日付別のファイルをすべて確認し、プロジェクトのドレインが書き込む場所も把握しています。プロジェクトにインストール済みのもの(pnpm evlog、または使用しているパッケージマネージャーに対応するコマンド)を優先してください。必要に応じて取得するラッパー(npx、bunx、npm exec)は、プロジェクトにない場合に @evlog/cli をインストールします。これにより、ロックファイルで固定されていないリリースが実行されます。実行する前に確認してください。
pnpm evlog logs --json # the last 50 events
pnpm evlog logs errors --since 1h --json # what failed
pnpm evlog logs slow --over 1s --json # what was slow, worst first
pnpm evlog logs "$REQUEST_ID" --json # one request, every event with that id
pnpm evlog logs stats --json # per route: count, errors, p50, p95; by status and level
pnpm evlog logs --where 'payment.amount>5000' --where audit.outcome=failure --json
--json はエンベロープ(sources、view、matched、events。stats の場合は stats を格納します)を出力します。フィルターは --since、--until、--level、--path、--status(500 または 5xx)、任意のドット区切りフィールドに対する --where field=value|field>n|field~regex|field|!field(繰り返し指定可能)、--limit、デフォルト以外のディレクトリを指定する --dir、および HTTP 経由で readMemoryLogs() を公開するメモリドレイン上のアプリ向けの --url です。モノレポのルートから実行すると、各アプリの .evlog/logs を読み取り、各イベントにラベルを付けます。ドキュメント:https://www.evlog.dev/cli/logs。CLI を利用できない場合、またはユーザーが利用を断った場合は、以下のようにファイルを直接読み取ります。
ログは evlog のファイルシステムドレインによって .jsonl ファイルに書き込まれ、日付別に整理されます。
形式の判定:ドレインは次の 2 つのモードに対応しています。
- NDJSON(デフォルト、
pretty: false):1 行につき 1 つのコンパクトな JSON オブジェクトです。行ごとに解析します。 - Pretty(
pretty: true):イベントごとに複数行のインデント付き JSON です。ファイル全体を読み取り、トップレベルのオブジェクトで分割して解析します(例:JSON.parse('[' + content.replace(/\}\n\{/g, '},{') + ']'))。またはストリーミング JSON パーサーを使用します。
ファイルの先頭数バイトを必ず確認し、形式を判定してください。2 文字目が改行または " なら NDJSON、スペースまたは空白に続く改行なら整形済み形式です。
検索順序。 プロジェクトルートからの相対パスで、次の場所を確認します。
.evlog/logs/(デフォルト)- アプリディレクトリ内にある
.evlog/logs/(モノレポの場合:apps/*/.evlog/logs/)
glob でログファイルを検索します。
.evlog/logs/*.jsonl
*/.evlog/logs/*.jsonl
apps/*/.evlog/logs/*.jsonl
ファイル名には日付が使われます:2026-03-14.jsonl。最も新しいファイルから確認してください。
プログラムによる読み取り:手動で解析する代わりに、小さなスクリプトで evlog に同梱されている evlog/fs の readFsLogs() および tailFsLogs() を使用できます。これらは両形式、日付順、フィルタリングに対応する非同期ジェネレーターです。プロジェクトに evlog がすでにインストールされており、簡単な grep 以上の分析が必要な場合は、これらを優先してください。
メモリドレインを使う方法:一部のアプリでは、FS ドレインの代わりに(または併用して)Memory アダプター(evlog/memory)を使用し、開発環境専用の HTTP エンドポイントを通じて readMemoryLogs() で最近のイベントを公開しています。.evlog/logs/ が空でも、アプリで createMemoryDrain() が設定されている場合は、そのエンドポイントにクエリしてください。
ログが見つからない場合
新しいドレインを設定する前に、npx evlog doctor --json を試すことができます。evlog がインストールされているか、ローカルに .evlog/logs ドレインがすでにあるかを確認します(読み取り専用)。任意です。CLI を利用できない場合は省略してください。
ファイルシステムドレインが有効になっていない可能性があります。Nuxt、Nitro、Next.js、TanStack Start、Hono、Express、または Fastify では、最も手早い方法は CLI を使うことです。フレームワークを検出し、fs ドレイン(デフォルトの開発用ドレイン)を一度に設定します。
npx evlog init --dry-run --yes # preview first
npx evlog init --yes --drain fs # apply
実行する前に確認してください。その他のフレームワークの場合(またはユーザーが利用を断った場合)は、手動で設定する方法を案内してください。
import { defineEvlog } from 'evlog'
import { createFsDrain } from 'evlog/fs'
// Nuxt / Nitro: evlog.config.ts at the app root, which the module loads
export default defineEvlog({ drain: createFsDrain() })
// Hono / Express / Elysia: pass in middleware options
app.use(evlog({ drain: createFsDrain() }))
// Fastify: pass in plugin options
await app.register(evlog, { drain: createFsDrain() })
// NestJS: pass in module options
EvlogModule.forRoot({ drain: createFsDrain() })
// Standalone: pass to initLogger
initLogger({ drain: createFsDrain() })
設定後、ユーザーにリクエストをいくつか実行してログを生成してもらい、その後、再度分析します。
ログ形式
各行は自己完結した JSON オブジェクト(ワイドイベント)です。主要なフィールド:
| フィールド | 型 | 説明 |
|---|---|---|
timestamp | string | ISO 8601 タイムスタンプ |
level | string | info、warn、error、debug |
service | string | サービス名 |
environment | string | development、production など |
method | string | HTTP メソッド(GET、POST など) |
path | string | リクエストパス(/api/checkout) |
status | number | HTTP レスポンスステータスコード |
duration | string | リクエスト所要時間(人間が読みやすい形式、"234ms") |
durationMs | number | リクエスト所要時間(ミリ秒)。フィルタとソートにはこちらを使用してください |
requestId | string | 一意のリクエスト識別子 |
error | object | エラーの詳細: name、message、stack、statusCode、data |
error.data.why | string | 何が問題だったかの人間が読める説明 |
error.data.fix | string | エラーに対する修正の提案 |
source | string | ブラウザログの場合は client、サーバーログの場合は存在しません |
userAgent | object | 解析済みのブラウザ/OS/デバイス情報 |
その他のすべてのフィールドは、log.set() を介して追加されるアプリケーション固有のコンテキストです(例: user、cart、payment)。
分析方法
ステップ 1: 最新のログファイルを読む
最新の .jsonl ファイルを読み込みます。各行は 1 つの JSON イベントです。各行を個別にパースします。
ステップ 2: 関連するイベントを特定する
ユーザーの質問に基づいてフィルタリングします:
- エラー:
"level"が"error"または"fatal"、status >= 500、またはイベントにerrorオブジェクトがあるもの。これがevlog logs errorsがマッチする対象です。4xx ステータス単体はクライアント側のものであり該当しませんが、4xx イベントでも他の 2 つのシグナルのいずれかを持つ場合はマッチします。それらをすべて確認するにはstatusを読むか、--status 4xxを渡してください - 特定のエンドポイント:
pathでマッチ - 遅いリクエスト:
durationMsでフィルタリング(例:durationMs > 500) - 特定のユーザー/アクション: アプリケーション固有のフィールドでマッチ
- クライアント側の問題:
"source":"client"でフィルタリング - 時間範囲:
timestampの値を比較
ステップ 3: 分析して説明する
関連する各イベントについて:
- 何が起きたか:
path、method、status、levelを要約します - なぜ失敗したか(エラー):
error.message、error.data.why、スタックトレースを読みます - 修正方法:
error.data.fixで提案された対処法を確認します - コンテキスト: アプリケーション固有のフィールドでビジネスコンテキスト(ユーザー情報、支払いの詳細など)を調べます
- パターン: 繰り返し発生するエラー、性能の低下、相関する障害を探します
分析パターン
すべてのエラーを検索する
Filter: level === "error"
Group by: error.message or path
Look for: recurring patterns, common failure modes
遅いリクエストを検索する
Filter: durationMs > 1000
Sort by: durationMs descending
Look for: specific endpoints, time-of-day patterns
特定のリクエストを追跡する
Filter: requestId === "the-request-id"
Result: single wide event with all context for that request
エンドポイント別のエラー率
Group events by: path
Count: total events vs error events per path
Look for: endpoints with high error ratios
クライアントとサーバーのエラー
Split by: source === "client" vs no source field
Compare: error patterns between client and server
Look for: client errors that don't have corresponding server errors (network issues)
重要な注意事項
- 各行は完全で自己完結したイベントです。従来のログとは異なり、複数の行を関連付ける必要はありません。1 行に 1 つのリクエストのすべてのコンテキストが含まれています。
error.data.whyとerror.data.fixフィールドは evlog 固有の構造化エラーフィールドです。存在する場合、最も実行可能な情報を提供します。durationは単位付きの人間が読みやすい形式です(例:"706ms")。durationMsは同じ所要時間をミリ秒で表したものです。フィルタとソートにはdurationMsを使用してください。"source":"client"を持つイベントはブラウザ側のログ記録に由来し、HTTP drain エンドポイントを介してサーバーに送信されました。- ログファイルは自動的に
.gitignoreに登録されます。これらはアプリが実行されているローカルマシンまたはサーバー上にのみ存在します。