mcpField
K
kubesense-logs

kubesense-logs

github.com/kubesense-aiクラウド・DevOps3101 回インストール3 日前に更新
リポジトリ

kubesense-logs について

kubesense-logs は、KubeSense MCP サーバー経由でログを扱うためのスキルです。個別行の取得と集計分析を使い分け、フィールド、条件式、ページングの制約を案内します。

主な機能

  1. 01ログフィールドカタログの確認
  2. 02個別ログ行の取得
  3. 03件数、傾向、パーセンタイルの集計
  4. 04カタログ名と WHERE 条件による絞り込み
  5. 05時間範囲ページングの制約説明

活用シーン

  1. 01ワークロードのエラーログ確認
  2. 02ワークロード別エラー件数の推移分析
  3. 03致命的エラーを記録した Pod 数の集計
  4. 04タイムアウトを含むログメッセージの検索

MCP 対応

このスキルには KubeSense MCP サーバーが必要で、ログフィールドカタログ、検索、分析ツールの呼び出し方を案内します。

インストール

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

$npx skills add https://github.com/kubesense-ai/kubesense-mcp-skills --skill kubesense-logs

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

詳細

KubeSense ログ

KubeSense MCP サーバーが必要です。接続、認証、共通の WHERE 句のリファレンスについては、kubesense-mcp を参照してください。ここにあるツールは、logs モジュールに対して RBAC を解決します。

ツール

ツール使用する場面戻り値
get-trace-or-log-fields (signal: "logs")必ず最初に使用対象時間枠のフィールドカタログ
search-logs個々のログ行を読みたい場合最大 page_size 行(デフォルトは 10)
analyze-logs件数、割合、傾向、パーセンタイルを知りたい場合集計系列

合計を計算するために行を読み込むのは、最もよくある間違いです。 質問が「いくつあるか」「どのくらいの頻度か」「どれが最悪か」であれば、analyze-logs を使用してください。生の行をページ分割して取得するよりも、対象時間枠全体を一度の呼び出しで処理するほうが正確です。

フィールド名 — カタログのラベルのみ

サーバーは、すべての入力箇所(where、required_fields、group_by_fields、fields、sort_by)で、ストレージの列名を拒否し、次のエラーを返します。

field "pod_name" is a storage column; use the catalog label "instance" instead
概念使用するラベルストレージ列(拒否)
ログの重要度typelevel
Podinstancepod_name
コンテナcontainercontainer_name
ノード/ホストnodehost
ワークロードworkload—
名前空間namespace—
クラスターcluster—
ログメッセージbody—
ログ形式format—
ソースsource—
リージョンregion—
アプリのバージョンapp_version—
環境env_type—

これは、get-trace-or-log-fields がログ用に公開する 13 個のフィールドのすべてです。 さらに 3 つのフィールドも解析されますが、検出結果には表示されません。timestamp、pattern_id、body_length です。

警告

ログには service フィールドがありません。 service が存在するのはトレースのみです(→ app_service)。ログに対して service = checkout を指定すると、unknown field "service" for signal=logs が返されます。アプリケーション名には workload を使用してください。

ログでは node、トレースでは node_name です。 2 つのシグナルで異なります。ログでは node(→ host)、トレースでは node_name を使用します。シグナル間でフィールド名をそのまま使うと、確実に失敗します。

ログの列挙値は大文字です

type が受け付ける値は、ERROR、WARN、INFO、DEBUG、TRACE、FATAL、PANIC のみです。大文字と小文字は区別されるため、type = error は何も一致しません。

(トレースでは小文字の status = error を使用します。2 つのシグナルでは、フィールド名と大文字・小文字の両方が異なります。)

format が受け付ける値は、小文字の json、klog、nginx です。

メモ

大文字・小文字の確認には、get-trace-or-log-fields の example 列ではなく、enum_values 列を参照してください。例の生成機能では、type を含む複数の列挙型フィールドが取得されず、空欄になります。enum_values は常に正しい値を返します。

WHERE 構文

type = ERROR AND namespace = production
type IN (ERROR, FATAL) AND workload = checkout
NOT (env_type = dev)
body ILIKE "%timeout%"
@user.id = abc-123

WHERE パーサーが実際に受け付ける演算子は、= != < > <= >= LIKE ILIKE SUBSTR_ILIKE IN です。これらは AND / OR / NOT および括弧と組み合わせて使用できます。

警告

get-trace-or-log-fields の operators 列は、実際よりも多くの演算子を宣伝しています。HAS_TOKEN、 HAS_ALL、HAS_ANY、LIKE_AND、ILIKE_LOG、IS_IP_ADDRESS は凡例に表示されていますが、 WHERE 文字列の構文としては使用できません。body HAS_TOKEN oom は解析に失敗します。 上記のリストを使用してください。

引用符の使用。 引用符なしの値に使用できるのは、英字、数字、_、.、- のみです。スラッシュ、 コロン、%、スペースを含む値は必ず二重引用符で囲んでください。

body ILIKE "%connection refused%"      ✓
timestamp > "2026-07-30T10:00:00Z"     ✓
body ILIKE %timeout%                   ✗ parse error

NOT IN はリーフとして解析されません。 NOT (namespace IN (kube-system, default)) のように記述してください。

属性は WHERE で @ プレフィックスを付けると、ログに対して正しく機能します。

@user.id = abc-123
@http.status_code > 400

属性で使用できる演算子は、= != IN < > <= >= LIKE ILIKE です。引用符で囲まれていない数値の属性値は数値に変換されるため、@latency > 100 は数値として比較されます。

警告

exist(@field) は両方のシグナルで機能しません。値を伴う EXIST 演算子が出力され、バリデーターに拒否されます(operator "EXIST" takes no values (got 1))。機能する存在チェックはありません。代わりに具体的な値でフィルターしてください。

group_by_fields / fields / required_fields / sort_by には @ を付けません。代わりにフラグを設定してください。

{ "field": "user.id", "is_attribute": true }

search-logs

{
  "from_time": "2026-07-30T10:00:00Z",
  "to_time": "2026-07-30T11:00:00Z",
  "where": "type = ERROR AND namespace = production",
  "required_fields": [
    { "field": "instance", "is_attribute": false },
    { "field": "body", "is_attribute": false }
  ],
  "page_size": 50
}

出力は TSV 形式です。# total_count=<N> error_count=<N> is_free_search=<bool> の行、ヘッダー行、続いてログごとに1行が出力されます。total_count は page_size を無視したウィンドウ全体の件数です。追加の結果があるかどうかは、受け取った行数と比較して確認してください。

ウィンドウベースのページネーション

page または offset パラメーターはありません。 ウィンドウは半開区間 (from_time <= timestamp < to_time)なので、to_time を狭めてページを取得します。

  1. 実際のウィンドウを指定してクエリを実行します。
  2. 返された行の timestamp の最小値を取得します。最後の行が最も古いとは限らないため、そう決めつけないでください。
  3. 同じ from_time と where を指定し、最小値をそのままコピーして to_time として、再度呼び出します。
  4. page_size より少ない行しか返されない場合、または結果が確定した場合に停止します。

タイムスタンプは、ミリ秒精度の RFC3339 UTC 形式です。セルの値をそのままコピーしてください。 秒単位に切り捨てると、その秒内の行を再取得したり、読み飛ばしたりします。

重要

ページ分割したスキャンは全件調査ではなくサンプルです。 行は toStartOfHour(timestamp) DESC, cluster DESC, timestamp DESC の順に並びます。まず時間単位のバケット、 次にクラスターで並べられます。複数のクラスターにまたがって、1時間分の一致行が page_size を超える場合、 to_time を進めると、スキャンがまだ到達していないクラスターの行を読み飛ばす可能性があります。すべての結果を 読み取るには、clusters を1つのクラスターに固定し、大きな page_size を使用してください。 それ以外の場合は、ページ数を増やすより page_size を大きくし、集計が必要な場合は ページネーションより analyze-logs を優先してください。

is_free_search

body、trace_id、span_id、またはいずれかの属性を参照すると、クエリは事前集計済みのロールアップではなく、 生テーブルに送られます。速度は遅くなりますが、メッセージ本文を確認する唯一の方法です。この値は自動的に計算され、 出力ヘッダーに報告されます。列のみを対象にしたフィルターは、高速なロールアップ経路を維持します。

ここでの body ILIKE "…" は、サーバー側で本文テキストインデックスを使用するよう書き換えられます。 生 SQL にはこの書き換えは適用されないため、検索の条件上必要でない限り、メッセージ検索を execute-sql に移さないでください。 必要な場合は、kubesense-sql の Searching Log Text に従ってください。

analyze-logs

{
  "from_time": "2026-07-30T10:00:00Z",
  "to_time": "2026-07-30T11:00:00Z",
  "query_type": "range",
  "where": "type = ERROR",
  "group_by_fields": [ { "field": "workload", "is_attribute": false } ],
  "value_operation": "row_count",
  "sort_direction": "DESC",
  "limit": 10
}
  • query_type:時系列の場合は range、系列ごとに1つの数値を返す場合は instant。
  • value_operation:row_count、unique_count、avg、sum、min、max、p50、 p90、p95、p99。
  • fields は、row_count 以外のすべての演算の対象フィールドを指定します。 ポッドの unique_count → value_operation: "unique_count"、 fields: [{"field": "instance"}]。
  • limit は range クエリの系列数を制限します(最大値順の上位N件。デフォルトは20)。instant では無視されます。

警告

value_operation: "count" は無効です。正しい名前は row_count です。ツールスキーマの概要行には「Common: count, avg, …」とありますが、これは誤りです。

body は group_by_fields では使用できません(ロールアップテーブルに存在しません)。フィルター専用フィールドです。類似メッセージをグループ化する場合は、pattern_id でグループ化してください。

出力形式

クエリラベル("A")をキーとする列指向のJSONです。range の場合、共通の timestamps 配列(Unix秒)が1回だけ出力され、各系列には位置が対応する values 配列が含まれます(null はそのバケットにデータがないことを示します)。instant の場合、各系列にはスカラー値の value が含まれます。total_series/truncated は、上位N件の制限を適用する前に存在したゼロ以外の系列数を示します。

使用例

過去1時間のワークロードごとのエラー数を傾向として確認する query_type: range、where: "type = ERROR"、 group_by_fields: [{"field":"workload"}]、value_operation: row_count

現時点で致命的なエラーを記録した個別のポッド数を確認する query_type: instant、where: "type = FATAL"、value_operation: unique_count、 fields: [{"field":"instance"}]

実際のタイムアウトメッセージを読む search-logs、where: 'body ILIKE "%timeout%" AND workload = checkout'、 required_fields: [{"field":"instance"},{"field":"body"}]、page_size: 50

エラー率をパーセンテージで確認する — 2つのクエリと数式が必要なため、 analyze-telemetry を使用してください。kubesense-mcp を参照してください。

ルール

  1. 最初に get-trace-or-log-fields を signal: "logs" とともに呼び出し、クエリに使用するものと同じ時間範囲を渡してください。属性キーは時間範囲ごとに異なります。
  2. カタログのラベルを使用してください:type、instance、container、node。level、pod_name、 container_name、host は使用しないでください。
  3. ログに service フィールドはありません。workload を使用してください。
  4. type の値は大文字です(error ではなく ERROR)。example ではなく、enum_values から大文字・小文字を確認してください。
  5. /、:、%、またはスペースを含む値は引用符で囲んでください。
  6. x NOT IN (...) ではなく、NOT (x IN (...)) を使用してください。
  7. = != < > <= >= LIKE ILIKE SUBSTR_ILIKE IN のみを使用してください。案内されているトークン/インデックス演算子にはWHERE句の構文がありません。
  8. value_operation は count ではなく row_count です。
  9. 件数や傾向の確認には analyze-logs を使用し、メッセージを読む場合に限り search-logs を使用してください。集計のためにページネーションを行わないでください。
  10. ページを進める際は、返されたタイムスタンプの最小値まで to_time を絞り込んでください。オフセットはありません。クラスターを固定しない限り、複数クラスターにまたがるページスキャンはサンプルとして扱ってください。
  11. body はフィルター専用で、グループ化には使用できません。

コメント