mcpField
O
oodle-logs

oodle-logs

github.com/oodle-aiクラウド・DevOps0125 回インストール3 週間前に更新
リポジトリ

oodle-logs について

oodle-logsは、OpenSearch Query DSLでOodleのログを検索し、利用可能なインデックスパターンを調べるスキルです。クエリ前のパターンとフィールドの確認、明示的な時間範囲の指定を案内します。

主な機能

  1. 01ログのインデックスパターンとフィールドの発見
  2. 02OpenSearch Query DSLによるNDJSONクエリ作成
  3. 03指定した時間範囲でのログ検索
  4. 04ログフィールドによる結果の集計
  5. 05jqを使ったクライアント側でのプレーンテキスト値抽出

活用シーン

  1. 01調査対象となるログイベントの検索
  2. 02サービス別のエラー件数集計
  3. 03過去のログ行の確認と埋め込み値の抽出

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/oodle-ai/agent-skills --skill oodle-logs

インストール後、Claude Code で/oodle-logsを入力して読み込まれたか確認します。

詳細

Oodle Logs — 検索とインデックスパターンの検出

このスキルでは、OpenSearch 互換のクエリー DSL を使ってログデータを検索し、利用可能なログのインデックスパターンを検出する方法を説明します。

前提条件

brew install oodle-ai/oodle/oodle
oodle configure

ログのエンドポイントが動作することを確認します。

oodle logs index-patterns -o json | jq 'length'

コマンドの実行順序

ログクエリーを実行する前に、次の手順に従います。

  1. oodle logs index-patterns -o json を実行して、利用可能なログのインデックスパターンを確認します。
  2. クエリーに適したインデックスパターンの title を選びます。
  3. 確認したインデックスパターンと OpenSearch Query DSL を使って、NDJSON クエリーファイルを作成します。
  4. 必要な期間をカバーするように --start と --end を設定します。デフォルト値は -1h と now です。
  5. インデックス名を推測してはいけません。必ず先に index-patterns で確認してください。

クイックリファレンス

タスクコマンド
ログのインデックスパターンを一覧表示oodle logs index-patterns -o json
ログを検索oodle logs query -f query.ndjson --start <start> --end <end> -o json

よく使う操作

ログのインデックスパターンを一覧表示

ログクエリーを作成する前に、利用可能なログのインデックスパターンを確認します。返される title フィールドは、NDJSON クエリーファイルの index 値として使用します。

# CORRECT — list all available index patterns
oodle logs index-patterns -o json

# CORRECT — extract just the pattern titles
oodle logs index-patterns -o json | jq '.[].title'

# CORRECT — use a discovered pattern in a log query
oodle logs index-patterns -o json | jq '.[].title'
# Then use the title in your NDJSON file:
# {"index": "logs-*"}
# {"query": {"match_all": {}}, "size": 10}
ログクエリー

OpenSearch 互換のマルチサーチ API を使ってログデータを検索します。リクエスト本文は NDJSON 形式で、JSON の行がちょうど 2 行含まれます。1 行目はインデックスを選択し、2 行目には OpenSearch Query DSL を使った検索クエリーを指定します。本文は -f <file> で渡します。

重要な制約:

  • CLI がサポートするのは単一の検索本文のみです(NDJSON の行がちょうど 2 行、ヘッダー 1 行と検索 1 行)。検索ペアを複数指定することはできません。
  • 時間範囲のフィルタリングには --start と --end フラグを使います。値にはエポックミリ秒(例:1716825600000)、RFC 3339(例:2026-01-02T00:00:00Z)、now、または相対表現(例:-1h、-24h、-7d)を指定できます。
  • --start のデフォルト値は -1h、--end のデフォルト値は now です。 1 時間より前のデータを検索する場合は、明示的に --start を指定する必要があります。指定しないと、クエリーの結果はエラーなく 0 件になります。
  • クエリー本文に timestamp の範囲フィルターを指定してはいけません。CLI が --start/--end から timestamp の範囲フィルターを自動挿入します。
# CORRECT — basic query (searches last 1 hour by default)
cat > query.ndjson <<'EOF'
{"index": "logs-*"}
{"query": {"match_all": {}}, "size": 10}
EOF
oodle logs query -f query.ndjson -o json

# CORRECT — search for specific log messages with explicit time range
cat > query.ndjson <<'EOF'
{"index": "logs-*"}
{"query": {"bool": {"must": [{"match_phrase": {"message": "error"}}]}}, "size": 50, "sort": [{"timestamp": {"order": "desc"}}]}
EOF
oodle logs query -f query.ndjson --start -6h --end now -o json

# CORRECT — search older data using relative time
cat > query.ndjson <<'EOF'
{"index": "logs-*"}
{"query": {"bool": {"must": [{"match_phrase": {"message": "OOMKilled"}}]}}, "size": 100}
EOF
oodle logs query -f query.ndjson --start -7d --end -6d -o json

# CORRECT — search older data using epoch milliseconds
cat > query.ndjson <<'EOF'
{"index": "logs-*"}
{"query": {"match_phrase": {"message": "connection refused"}}, "size": 50}
EOF
oodle logs query -f query.ndjson --start 1716825600000 --end 1716912000000 -o json

# WRONG — omitting --start when searching for data older than 1 hour
cat > query.ndjson <<'EOF'
{"index": "logs-*"}
{"query": {"match_phrase": {"message": "yesterday's deploy error"}}, "size": 50}
EOF
oodle logs query -f query.ndjson -o json
# ^^^ Returns 0 results! --start defaults to -1h, so older data is excluded.
# FIX: add --start -24h (or whatever range covers the target timeframe)

# WRONG — putting a range filter on timestamp in the query body
cat > query.ndjson <<'EOF'
{"index": "logs-*"}
{"query": {"bool": {"must": [{"range": {"timestamp": {"gte": "now-1h", "lte": "now"}}}]}}, "size": 100}
EOF
# The CLI already injects a timestamp range from --start/--end. In-query range filters conflict.
# FIX: use --start and --end flags instead.

# WRONG — passing the query inline without -f
oodle logs query --body '{"index":"logs-*"}'

# WRONG — using JSON instead of NDJSON format
oodle logs query -f query.json   # file must be valid NDJSON (exactly two lines)
集計

OpenSearch の集計は aggs ブロックに指定します。集計結果のみが必要な場合は "size": 0 を設定します。結果は jq '.responses[0].aggregations' で読み取ります。以下のフィールド名は例です。oodle logs index-patterns で実際のフィールドを確認してください。数値の集計には、message 内のテキストではなく、数値フィールドが必要です。

# CORRECT — error lines per service (top 20)
cat > query.ndjson <<'EOF'
{"index": "logs-*"}
{"size": 0, "query": {"term": {"level": "error"}}, "aggs": {"by_service": {"terms": {"field": "service_name", "size": 20}}}}
EOF
oodle logs query -f query.ndjson --start -24h --end now -o json \
  | jq -r '.responses[0].aggregations.by_service.buckets[] | "\(.key)\t\(.doc_count)"'

# CORRECT — error lines per hour
cat > query.ndjson <<'EOF'
{"index": "logs-*"}
{"size": 0, "query": {"match_phrase": {"message": "error"}}, "aggs": {"per_hour": {"date_histogram": {"field": "timestamp", "fixed_interval": "1h"}}}}
EOF
oodle logs query -f query.ndjson --start -24h --end now -o json \
  | jq -r '.responses[0].aggregations.per_hour.buckets[] | "\(.key_as_string)\t\(.doc_count)"'
プレーンテキストのログ行に含まれる値

regexp クエリー、スクリプト、ランタイムフィールドはサポートされていません。そのため、プレーンテキストのログ行のテキスト内にしか存在しない値では、ログクエリーによるフィルタリングやグループ化はできません。tool Bash ok in 12345 ms のような行を対象にする場合、クエリーで「10000 ms 超」を選択したり、ツール名でグループ化したりすることはできません。Oodle では実現できないとユーザーに伝えてはいけません。次のいずれかを提案してください。

  1. ログメトリクスルール(oodle-log-metrics スキル):正規表現で値を抽出し、ラベル付きのメトリクスにします。新しいログに対するカウント、レイテンシー、アラートに使用します。
  2. 過去のデータ:match_phrase で該当する行を見つけ、クライアント側で jq を使って値を抽出します。
必要な操作使用するもの
行の検索、イベントの確認、過去の調査oodle logs query
過去のデータで実際のフィールドをカウントまたはグループ化aggs を使った oodle logs query
プレーンテキスト内にしか存在しない値でのフィルタリングまたはグループ化ログメトリクスルール(新しいデータ)、またはクライアント側で jq(過去のデータ)
ログ行のアラート(カウント、レート、レイテンシー、ユーザーごと)ログメトリクスルール + モニター
ダッシュボードで数週間にわたる傾向を表示ログメトリクスルール
実例:過去24時間にクレジットが切れたユーザーを調べる

まず、これらの行をカウントするログメトリクスルールがすでにあるか確認します:oodle log-metrics list -o json。ルールがある場合は、そのメトリクスを確認します。たとえば、oodle metrics query --query 'sum by (user) (increase(oodle_logs_credit_exhausted[24h])) > 0' -o json を実行します。ルールがカウントするのは、作成後に届いた行だけです。古いデータには、以下のログを使用してください。

cat > credit.ndjson <<'EOF'
{"index": "logs-*"}
{"query": {"match_phrase": {"message": "credit exhausted"}}, "size": 1000, "sort": [{"timestamp": {"order": "desc"}}]}
EOF

# If the user is a real field (for example user_id): use a terms aggregation on it.
# If the user is only inside the text ("... for user=alice ..."): extract it on the client.
oodle logs query -f credit.ndjson --start -24h --end now -o json \
  | jq -r '.responses[0].hits.hits[]._source.message | capture("user=(?<user>[^ ]+)").user' \
  | sort | uniq -c | sort -rn

クエリが size 件の行を返した場合、さらに結果がある可能性があります。時間範囲を分割し(たとえば、6時間のクエリを4回実行)、結果をまとめてください。今後、ユーザーごとにアラートを出すには、正規表現 user=(\S+) で user を抽出するログメトリクスルールと、sum by (user) (increase(oodle_logs_credit_exhausted[10m])) によるモニターを作成します。ルールの JSON は oodle-log-metrics スキルにあります。

ベストプラクティス

クエリを実行する前にインデックスパターンを確認する

正しいインデックス名を見つけるため、必ず oodle logs index-patterns を実行してください。インデックス名を推測すると、空の結果が返されたり、エラーになったりすることがあります。

# CORRECT — discover first, then query
oodle logs index-patterns -o json | jq '.[].title'
# Use the discovered title in your NDJSON file

# WRONG — guessing index names
cat > query.ndjson <<'EOF'
{"index": "my-logs"}
{"query": {"match_all": {}}, "size": 10}
EOF
oodle logs query -f query.ndjson -o json
時間範囲の絞り込みには必ず --start と --end を使う

CLI は --start/--end に基づく timestamp の範囲フィルターを自動的に追加します。クエリ本文に独自の timestamp 範囲フィルターを追加しないでください。CLI が追加するフィルターと競合します。

# CORRECT — use CLI flags for time range
oodle logs query -f query.ndjson --start -24h --end now -o json

# CORRECT — use epoch milliseconds for precise ranges
oodle logs query -f query.ndjson --start 1716825600000 --end 1716912000000 -o json

# WRONG — relying on the default 1-hour window for older data
oodle logs query -f query.ndjson -o json
# ^^^ Only searches the last 1 hour. If the data you need is older, you get 0 results.

# WRONG — putting range filters on timestamp in the query body
{"query": {"bool": {"must": [{"range": {"timestamp": {"gte": "now-6h"}}}]}}}
# FIX: remove the range from the query body and use --start -6h instead.
ログクエリの結果には -o json を使う

ログクエリのレスポンスには、ネストされた JSON 構造が含まれます。必ず -o json を使い、jq に渡して値を抽出してください。

# CORRECT — extract log messages from the response
oodle logs query -f query.ndjson -o json | jq '.responses[].hits.hits[]._source.message'

# WRONG — using table output for complex nested log data
oodle logs query -f query.ndjson -o table
インデックスパターンのフィールドを使って正確なクエリを作成する

各インデックスパターンには、フィールド名と型を含む fields 配列があります。match_all を使う代わりに、これらを利用して対象を絞ったクエリを作成してください。

# CORRECT — check available fields first
oodle logs index-patterns -o json | jq '.[0].fields[].name'
# Then build a query using confirmed field names

エラーへの対処

エラー原因対処方法
401 UnauthorizedAPI キーが無効、または設定されていないoodle configure を実行するか、OODLE_API_KEY を設定します
400 Bad RequestNDJSON 本文または Query DSL が無効NDJSON ファイルがちょうど2行であることを確認し、OpenSearch Query DSL の構文を確認します
空の結果(エラーではない)インデックスまたは時間範囲に一致するログがない時間範囲を広げるか、oodle logs index-patterns でインデックス名を確認します
古いデータの結果が0件--start の既定値は -1h であり、その範囲外のデータは除外される古いデータには --start を明示します。例:--start -24h または --start <epoch_ms>
connection refusedOODLE_DEPLOYMENT の URL が正しくないOODLE_DEPLOYMENT 環境変数を確認し、末尾にスラッシュがないことを確認します
429 Too Many Requestsレート制限に達している--retries 3 を追加し、待機時間を置いて、クエリの頻度を減らします
regexp、script、またはランタイムフィールドで400エラーサポートされていないmatch_phrase またはログメトリクスルールを使います(「プレーンテキストのログ行内の値」を参照)
required flag(s) "file" not setログクエリに必要なフラグが指定されていないNDJSON ファイルのパスを指定して -f フラグを追加します

参考資料

コメント