kubesense-traces について
kubesense-tracesは、KubeSenseで分散トレースを分析するスキルです。リクエストのレイテンシ、エラー、サービス間の呼び出しを調べる運用担当者向けに、分析・検索・トレースツリーのツールと、フィールド、時間単位、ページングの制約を案内します。
主な機能
- 01サービス別のレイテンシとエラー傾向の分析
- 02個々のスパンの検索
- 03リクエストの分散呼び出しチェーンの確認
- 04フィールドと列挙値の使用規則
- 05時間単位とページング制限の説明
活用シーン
- 01トレース内で失敗した呼び出し箇所の特定
- 02サービス間のp95・p99レイテンシの比較
- 03特定のHTTPステータスコードのエラー検索
- 04トレース結果をもとにログ調査を継続
MCP 対応
このスキルはKubeSense MCPサーバーへの接続を必要とし、tracesモジュールのツールを使用します。MCPクライアントによる分析、検索、分散トレースツールの呼び出し方法を案内します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kubesense-ai/ kubesense-mcp-skills --skill kubesense-tracesインストール後、Claude Code で/kubesense-tracesを入力して読み込まれたか確認します。
詳細
KubeSense Traces(APM)
リクエストに関するあらゆる内容に使用します。レイテンシー、p99/p95、エラー率、HTTP メソッド、ステータスコード、エンドポイント、サービス間呼び出し、下流の依存関係などです。(ログ行やパニックについては → kubesense-logs。)
KubeSense MCP サーバーが必要です。**kubesense-mcp**を参照してください。
ツールは traces モジュールに対して RBAC を解決します。
ツール
| ツール | 使用する場面 |
|---|---|
get-trace-or-log-fields (signal: "traces") | 常に最初に使用 |
analyze-traces | レイテンシーパーセンタイル、エラー率、件数、傾向 |
search-traces | 個々のスパンを確認 |
get-distributed-trace | trace_idがあり、呼び出しチェーン全体が必要な場合 |
get-distributed-traceは、ここで最も効果の高いツールです。 1つのスパンからは何かが失敗したことがわかりますが、トレースからはどのホップで失敗し、どこで時間がかかったかがわかります。
フィールド名 — カタログのラベルのみ
ストレージの列名は、すべての入力欄で拒否されます。
| 概念 | 使用するラベル | ストレージ列(拒否) |
|---|---|---|
| サービスの識別子 | service | app_service |
| k8s ワークロード | workload | — |
| ポッド | instance | pod_name |
| コンテナー | container | container_name |
| ノード | node_name | — |
| HTTP メソッド | method | subtype |
| HTTP ステータスコード | status_code | return_code |
| リソース/エンドポイント | resource | clustered_resource |
| スパンの役割 | role | kind |
| プロトコル | protocol | protocol_type |
| スパンの結果 | status | — |
| レイテンシー | duration | — |
| 外部呼び出しかどうか | request_type | is_external |
| 問題の理由 | reason | issue_reason |
| 顧客/テナント | domain | customer_identifier |
| トレース/スパン ID | trace_id, span_id | — |
| 問題 ID | issue_id | — |
| namespace、cluster、region、app_version、env_type、source、server、client、server_namespace、client_namespace、operation_name、partner_cluster | 同じ | — |
検出対象には表示されませんが、次の項目も解析します。timestamp(→ start_timestamp)、duration、
primary_workload/primary_namespace(→ perspective_*)、
associate_workload/associate_namespace(→ partner_*)。
serviceとworkload
アプリケーションの識別には**service**を優先してください。これはプラットフォームをまたいで使える識別子です(Kubernetes、Docker、レガシー環境)。Kubernetes のトポロジーが特に必要な場合に限り、workloadを使用してください。
メモ
アラートルールの場合のガイダンスとは逆です。アラートルールでは、
workloadのほうがより確実にグループ化されます。kubesense-alertsを参照してください。アラートエンジンはserviceをロールアップ列に対して解決しますが、この列に値が設定されるのは SDK で計装されたサービスのみです。
警告
トレースで
nodeは使用できません。正しくはnode_nameです。(ログでは逆にnodeであり、node_nameではありません。)シグナルをまたいでフィールド名を使い回さないでください。トレースに
bodyフィールドはありません。 メッセージ本文のテキスト検索はログでのみ可能です。
列挙値はトレースでは小文字
| フィールド | 値 |
|---|---|
status | error、ok |
role | server、client |
protocol | HTTP、gRPC、TCP、MongoDB、Redis、MySQL、PostgreSQL |
method | GET、POST、PUT、DELETE、PATCH |
source | eBPF、OTel |
status_code | 200、400、401、403、404、500、502、503、504 |
status = errorは小文字です。ログの大文字表記type = ERRORとは異なります。
status_codeは文字列フィールドです。そのため、数値に見える場合でも値は引用符付きの文字列のままです。status_code IN (500, 502)は文字列"500"、"502"を返します。したがって、範囲比較は機能しません。コードを列挙するか、クラスを指定するにはstatus_code LIKE "5%"を使用してください。
大文字・小文字の表記はexampleではなく、enum_values列で確認してください。例の生成機能では、method、protocol、status_codeのセルが空欄になります。
期間:入力はミリ秒、出力はナノ秒
重要
durationのフィルタリングではミリ秒を使います。集計結果のdurationはナノ秒です。 同じフィールド内で単位が異なり、間違えてもエラーは表示されません。
where: "duration > 500" → spans slower than 500 milliseconds
パーサーは値に 1e6 を掛けて、ナノ秒のストレージ列に変換します。したがって、次のようになります。
| 条件 | 記述 |
|---|---|
| 250ms より遅い | duration > 250 |
| 1s より遅い | duration > 1000 |
| 1.5s より遅い | duration > 1.5e3 または duration > 1500 |
警告
search-tracesツールの説明には、例として"duration > 250000"と記載されていますが、これは 誤りです。250,000ms = 250 秒を意味し、何も一致しません。無視してください。
集計は逆方向です。fields: [{"field": "duration"}] に対する
p95/avg/max は、ナノ秒で返されます。
| 結果 | 意味 |
|---|---|
250000000 | 250ms |
1000000000 | 1s |
ミリ秒で報告するには、1e6 で割ってください。MCP レイヤーには duration_ms フィールドはありません。
未知のフィールドとして拒否されます。
トレース属性:グループ化のみ
警告
トレースの WHERE 句では
@attrは機能しません。unknown field "<key>" for signal=tracesで拒否されます。 これは、ARRAY_MAP の再マッピング中にパーサーが属性の識別子をクリアし、その後フィールドの列検証に失敗するためです。 ツールの説明では@db.system = postgresqlが機能するとされていますが、実際には機能しません。
トレース属性は、フィールドを構造体として渡す場合はどこでも機能します。プレフィックスの代わりにフラグを設定してください。
"group_by_fields": [ { "field": "db.system", "is_attribute": true } ]
group_by_fields、fields、required_fields、sort_by で有効です。属性値でフィルタリングするには、その属性でグループ化して系列ラベルを確認するか、同等のトップレベル列でフィルタリングしてください。
(ログ属性には影響しません。ログでは @user.id = abc が問題なく機能します。)
analyze-traces
{
"from_time": "2026-07-30T10:00:00Z",
"to_time": "2026-07-30T11:00:00Z",
"query_type": "range",
"group_by_fields": [ { "field": "service", "is_attribute": false } ],
"fields": [ { "field": "duration", "is_attribute": false } ],
"value_operation": "p95"
}
value_operation:row_count、unique_count、avg、sum、min、max、p50、p90、
p95、p99。スキーマの概要行に記載されている内容にかかわらず、count は無効です。row_count を使ってください。
| 質問 | 形式 |
|---|---|
| 時系列でサービス別の p95 レイテンシを調べる | range、service でグループ化、fields: [duration]、p95 |
| 現在、エラー数が多い上位 5 サービスを調べる | instant、where: "status = error"、service でグループ化、row_count、sort_direction: DESC、limit: 5 |
| ステータスコード別のエラー数を調べる | instant、where: "status = error"、status_code でグループ化、row_count |
| 最も遅いエンドポイントを調べる | instant、resource でグループ化、fields: [duration]、p99、sort_direction: DESC |
| サーバー側のみを対象にする | where: "role = server" を追加します。追加しないとクライアントのスパンが二重にカウントされます |
エラー率をパーセンテージで求めるには、2 つのクエリと数式が必要です。→ analyze-telemetry を使ってください。
kubesense-mcp を参照してください。
出力は列指向の JSON です。range では、共有の timestamps 配列と、各系列に対応する位置で整列された values 配列が返されます。instant では、各系列につきスカラー値の value が 1 つ返されます。
search-traces
入力形式は search-logs と同じです。出力は、# total_count=<N> is_free_search=<bool> ヘッダーを含む TSV です。
ページネーション — そしてその厳しい制限
返された start_timestamp の最小値に to_time を絞り込んでページングします(timestamp ではありません。これはスパンの終了時刻です。start_timestamp がソートとフィルタリングのキーです)。ウィンドウは半開区間なので、カーソル行は重複しません。
警告
トレースを網羅的にページングすることはできません。 行は
toStartOfHour(start_timestamp) DESC, observation_point DESC, cluster DESC, start_timestamp DESCの順に並びます。observation_pointとclusterはどちらもタイムスタンプより優先されるため、clustersだけを固定しても不十分です。同じ時間帯の別の観測ポイントにあるスパンがスキップされます。また、observation_pointはトレースのフィールドカタログに含まれていないため、where句で固定できません(ツールの説明では"observation_point = s-app"が提案されていますが、未知のフィールドとして拒否されます)。実際の運用では、
total_countが1ページに収まるようにウィンドウを短くするか、analyze-tracesを使用してください。ページングによるトレースのスキャンは、サンプルとして扱ってください。
duration、trace_id、span_id、または任意の属性に触れると is_free_search が設定され、未加工のテーブルにルーティングされます。処理が遅く、ロールアップはありません。
get-distributed-trace
1つのリクエストのスパンツリーです。失敗または遅延しているリクエストを調査するときは、ここから始めてください。
{
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"from_time": "2026-07-30T10:20:00Z",
"to_time": "2026-07-30T10:40:00Z",
"max_spans": 200
}
trace_id、from_time、to_time はすべて必須です。ウィンドウにはトレースの start_timestamp を含める必要があります。トレースは時間でパーティション分割されるため、これを含まないウィンドウでは何も見つかりません。前後それぞれ約10分を指定してください。max_spans のデフォルトは200、最大値は500です。
メモ
スパンの
kuidではなく、trace_idをキーにしてください。1つのトレースには複数のスパンがあり、すべて同じtrace_idを共有します。
出力の読み方
ブロック1 — 先行順でスパンごとに1行表示されます(スパンの直後に子スパンが続きます)。tree 列には呼び出しチェーンが表示されます。主な列は次のとおりです。
| 列 | 確認する内容 |
|---|---|
tree | 誰が誰を呼び出したか |
status / return_code | どのスパンが失敗したか |
duration_us | すべての呼び出し先を含むスパン全体の時間。単位はマイクロ秒です |
self_time_us | 子スパンを除いた、このサービスでの時間 — ボトルネックのランキングに使います |
start_time / end_time | RFC3339形式のミリ秒。search-logs にそのまま貼り付けられます |
workload / namespace / cluster | ログ/メトリクスを追加でクエリする対象範囲 |
resource_name / protocol_type / subtype | 呼び出された対象 |
ブロック2 — ## services。クラスタとワークロードの組み合わせごとに1行で、エラー数、次に自己時間の降順で問題が大きい順に並びます。疑わしい対象を選ぶため、スパンの行を読む前に確認してください。ブロック1が途中で切り詰められていても、常にすべてのスパンが含まれます。
2つの診断ルール
- エラーのないトレースでも問題の原因である可能性があります。
## servicesの最上位の行は、時間を消費したホップです。 duration_usが大きく、self_time_usが小さい場合、そのサービスは作業中ではなく待機していました。 サービス自体ではなく、呼び出し先(子スパン)を調査してください。反対に、あるスパンでエラーが発生していて、すべての子スパンが成功している場合、障害はそのサービス内にあります。
スパンがワークロードのポッドではなくコレクターエージェントに割り当てられている場合、namespace は空欄になることがあります。値があるスパン行から取得するか、get-workload-detail から取得してください。まれに | で連結された複数の名前空間が表示されることがあります。これは、そのクラスタで同じワークロード名が複数の名前空間に存在することを意味します。
調査フロー
1. get-distributed-trace(trace_id, ±10min) → the call chain, errors marked
2. read "## services" → who owns the errors / the time
3. search-logs → scoped to that workload + the failing
span's start_time/end_time (widen a few s)
4. get-recent-changes / get-infra-issues → why: deploy, OOM, probe failure
5. analyze-metrics → confirm resource pressure
手順4~5では、kubesense-infra と kubesense-metrics を使用します。
ルール
- クエリと同じ時間範囲で、まず
signal: "traces"を指定してget-trace-or-log-fieldsを実行します。 - カタログのラベルのみを使用します:
service、instance、method、status_code、resource、role、protocol。app_service、pod_name、subtype、return_code、clustered_resource、kind、protocol_typeは使用しません。 - トレースでは
node_name、ログではnodeを使用します。フィールドをシグナル間で使い回してはいけません。 - アプリの識別には
workloadよりserviceを優先します。ただし、アラートエンジンではworkloadが優先されます。 - WHERE 内の
durationはミリ秒、集計されたdurationはナノ秒です。 結果を報告する際は 1e6 で割ってミリ秒にします。ここではduration_msは存在しません。 @attrフィルターはトレースでは機能しません。代わりに、group_by_fields/fieldsでis_attribute: trueを使用します。- 列挙値は小文字です(
status = error、role = server)。status_codeは文字列なので、コードを列挙するか、範囲指定の代わりにLIKE "5%"を使用します。 value_operationはcountではなくrow_countです。- リクエストをカウントする際は
role = serverを追加します。そうしないと、クライアントのスパンが二重にカウントされます。 get-distributed-traceでは、トレースの開始時刻を含む時間範囲が必要です。見つからない場合は、先に時間範囲を広げます。- トレースを網羅的にページ取得しようとしないでください。
observation_pointを固定できません。時間範囲を短くするか、集計してください。