mcpField
T
tempo

tempo

github.com/julianobarbosaクラウド・DevOps15106 回インストール4 日前に更新
リポジトリ

tempo について

tempoは、OpenTelemetry向け分散トレーシングバックエンドGrafana Tempoの運用とクエリに関するスキルです。デプロイ、ストレージ、TraceQL、マルチテナンシー、トラブルシューティングを扱い、Tempoの運用チーム向けです。

主な機能

  1. 01Tempoのアーキテクチャとデプロイ方式の解説
  2. 02Helmを使ったデプロイ手順
  3. 03S3、GCS、Azureストレージの説明
  4. 04TraceQLクエリ例
  5. 05受信プロトコルとエンドポイントの記載
  6. 06マルチテナンシーと障害対応の説明

活用シーン

  1. 01Tempoのデプロイ方式を検討
  2. 02トレース用オブジェクトストレージを設定
  3. 03TraceQLでトレースを検索
  4. 04取り込み、クエリ、認可の問題を調査

インストール

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

$npx skills add https://github.com/julianobarbosa/claude-code-skills --skill tempo

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
configuration.md
storage.md
traceql.md

詳細

Grafana Tempo スキル

OpenTelemetry 向けに設計された、コスト効率に優れた大規模分散トレーシングバックエンド、Grafana Tempo の包括的なガイドです。

Tempo とは?

Tempo は、次の特徴を持つ大規模分散トレーシングバックエンドです。

  • トレース ID 検索モデル - すべての属性をインデックス化しないため、取り込みが高速でストレージコストを抑えられます
  • OpenTelemetry ネイティブ - OTLP プロトコルを第一級でサポートします
  • オブジェクトストレージを利用 - 手頃な価格の S3、GCS、Azure Blob Storage にトレースを保存します
  • TraceQL クエリ言語 - PromQL と LogQL に着想を得た強力なクエリ言語です
  • Apache Parquet 形式 - 従来の形式と比較して、クエリごとに読み込むデータ量を 5~10 倍削減します
  • デフォルトでマルチテナント - X-Scope-OrgID ヘッダーによるテナント分離が組み込まれています

アーキテクチャの概要

コアコンポーネント
コンポーネント目的
Distributorトレースデータのエントリーポイントです。一貫性ハッシュリングを介して Ingester にルーティングします
Ingesterトレースをメモリにバッファリングし、Parquet ブロックを作成してストレージにフラッシュします
Query Frontendクエリを調整し、blockID の領域をシャード化して、Querier と連携します
Querierブルームフィルターを使って、Ingester またはストレージ内のトレースを検索します
Compactorブロックを圧縮し、データの重複を排除して、保持期間を管理します
Metrics Generatorオプション:トレースからメトリクスを導出します
データフロー

書き込みパス:

Applications → Collector → Distributor → Ingester → Object Storage
                                  ↓
                           Consistent Hash Ring
                           (routes by traceID)

読み取りパス:

Query Request → Query Frontend → Queriers → Ingesters (recent data)
                      ↓                            ↓
                 Block Sharding          Object Storage (historical data)
                      ↓                            ↓
              Parallel Querier Work      Bloom Filters + Indexes

デプロイモード

1. モノリシックモード(-target=all)
  • すべてのコンポーネントを単一プロセスで実行します
  • 適している用途:ローカルテスト、小規模なデプロイ
  • コンポーネント数を水平スケーリングできません
  • レプリカ数を増やしてスケールします
2. スケーラブルモノリシック(-target=scalable-single-binary)
  • すべてのコンポーネントを 1 つのプロセスで実行し、水平スケーリングできます
  • 各インスタンスですべてのコンポーネントを実行します
  • スケーリングが必要な開発環境に適しています
3. マイクロサービスモード(分散型)- 本番環境に推奨
# Using tempo-distributed Helm chart
distributor:
  replicas: 3

ingester:
  replicas: 3

querier:
  replicas: 2

queryFrontend:
  replicas: 2

compactor:
  replicas: 1

Helm デプロイ

リポジトリを追加
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
分散型 Tempo をインストール
helm install tempo grafana/tempo-distributed \
  --namespace monitoring \
  --values values.yaml
本番環境向けの値の例
# Storage configuration
storage:
  trace:
    backend: azure  # or s3, gcs
    azure:
      container_name: tempo-traces
      storage_account_name: mystorageaccount
      use_federated_token: true  # Workload Identity

# Distributor
distributor:
  replicas: 3
  resources:
    requests:
      cpu: 500m
      memory: 2Gi
    limits:
      memory: 4Gi

# Ingester
ingester:
  replicas: 3
  resources:
    requests:
      cpu: 1000m
      memory: 2Gi
    limits:
      memory: 8Gi  # Spikes to 8GB periodically
  persistence:
    enabled: true
    size: 20Gi

# Querier
querier:
  replicas: 2
  resources:
    requests:
      cpu: 100m
      memory: 256Mi
    limits:
      memory: 4Gi

# Query Frontend
queryFrontend:
  replicas: 2
  resources:
    requests:
      cpu: 100m
      memory: 100Mi
    limits:
      memory: 2Gi

# Compactor
compactor:
  replicas: 1
  resources:
    requests:
      cpu: 500m
      memory: 2Gi
    limits:
      memory: 6Gi

# Block retention
compactor:
  compaction:
    block_retention: 336h  # 14 days

# Gateway for external access
gateway:
  enabled: true
  replicas: 1

# Metrics Generator (optional)
metricsGenerator:
  enabled: false

ストレージの設定

Azure Blob Storage(Azure に推奨)
storage:
  trace:
    backend: azure
    azure:
      container_name: tempo-traces
      storage_account_name: <storage-account-name>
      # Option 1: Workload Identity (Recommended)
      use_federated_token: true
      # Option 2: User-Assigned Managed Identity
      use_managed_identity: true
      user_assigned_id: <identity-client-id>
      # Option 3: Account Key (Dev only)
      # storage_account_key: <account-key>
      endpoint_suffix: blob.core.windows.net
      hedge_requests_at: 400ms
      hedge_requests_up_to: 2
AWS S3
storage:
  trace:
    backend: s3
    s3:
      bucket: my-tempo-bucket
      region: us-east-1
      endpoint: s3.us-east-1.amazonaws.com
      # Use IAM roles or access keys
      access_key: <access-key>
      secret_key: <secret-key>
Google Cloud Storage
storage:
  trace:
    backend: gcs
    gcs:
      bucket_name: my-tempo-bucket
      # Uses Workload Identity or service account

TraceQL クエリ言語

基本的なクエリ
# Simplest query - all spans
{ }

# Filter by service
{ resource.service.name = "frontend" }

# Filter by operation
{ span:name = "GET /api/orders" }

# Filter by status
{ span:status = error }

# Filter by duration
{ span:duration > 500ms }

# Multiple conditions
{ resource.service.name = "api" && span:status = error }
構造演算子
# Direct parent-child relationship
{ resource.service.name = "frontend" } > { resource.service.name = "api" }

# Ancestor-descendant relationship
{ span:name = "GET /api/products" } >> { span.db.system = "postgresql" }

# Sibling relationship
{ span:name = "span-a" } ~ { span:name = "span-b" }
集計関数
# Count spans
{ } | count() > 10

# Average duration
{ } | avg(span:duration) > 20ms

# Max duration
{ span:status = error } | max(span:duration)
メトリクス関数
# Rate of errors
{ span:status = error } | rate()

# Count over time
{ span:name = "GET /:endpoint" } | count_over_time()

# Percentile latency
{ span:name = "GET /:endpoint" } | quantile_over_time(span:duration, .99)

# Group by service
{ span:status = error } | rate() by(resource.service.name)

# Top 10 by error rate
{ span:status = error } | rate() by(resource.service.name) | topk(10)

トレースの構造

固有フィールド(区切り文字はコロン)
フィールド説明
span:name操作名
span:duration経過時間(例:「10ms」、「1.5s」)
span:statusok、error、または unset
span:kindserver、client、producer、consumer、internal
trace:durationトレース全体の時間
trace:rootNameルートスパン名
trace:rootServiceルートスパンのサービス
属性スコープ(区切り文字はピリオド)
スコープ例説明
span.span.http.methodスパンレベルの属性
resource.resource.service.nameリソース属性
event.event.exception.messageイベント属性
link.link.traceIDリンク属性

レシーバーのエンドポイント

プロトコルポートエンドポイント
OTLP gRPC4317/v1/traces
OTLP HTTP4318/v1/traces
Jaeger gRPC14250-
Jaeger Thrift HTTP14268/api/traces
Jaeger Thrift Compact6831UDP
Jaeger Thrift Binary6832UDP
Zipkin9411/api/v2/spans

マルチテナント

# Enable multi-tenancy
multitenancy_enabled: true

# All requests must include X-Scope-OrgID header
# Example:
# curl -H "X-Scope-OrgID: tenant-1" http://tempo:3200/api/traces/<traceID>

Azure ID の設定

ワークロード ID フェデレーション(推奨)

1. AKS でワークロード ID を有効にする:

az aks update \
  --name <aks-cluster> \
  --resource-group <rg> \
  --enable-oidc-issuer \
  --enable-workload-identity

2. ユーザー割り当てマネージド ID を作成する:

az identity create \
  --name tempo-identity \
  --resource-group <rg>

IDENTITY_CLIENT_ID=$(az identity show --name tempo-identity --resource-group <rg> --query clientId -o tsv)

3. ストレージ権限を割り当てる:

az role assignment create \
  --role "Storage Blob Data Contributor" \
  --assignee-object-id <principal-id> \
  --scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<storage>

4. フェデレーション資格情報を作成する:

az identity federated-credential create \
  --name tempo-federated \
  --identity-name tempo-identity \
  --resource-group <rg> \
  --issuer <aks-oidc-issuer-url> \
  --subject system:serviceaccount:monitoring:tempo \
  --audiences api://AzureADTokenExchange

5. Helm の値を設定する:

serviceAccount:
  annotations:
    azure.workload.identity/client-id: <IDENTITY_CLIENT_ID>

podLabels:
  azure.workload.identity/use: "true"

storage:
  trace:
    azure:
      use_federated_token: true

トラブルシューティング

よくある問題

1. コンテナーが見つからない(Azure)

az storage container create --name tempo-traces --account-name <storage>

2. 認可エラー(Azure)

# Verify RBAC assignment
az role assignment list --scope <storage-scope>

# Assign if missing
az role assignment create \
  --role "Storage Blob Data Contributor" \
  --assignee-object-id <principal-id> \
  --scope <storage-scope>

3. Ingester のメモリ不足

ingester:
  resources:
    limits:
      memory: 16Gi  # Increase from 8Gi

4. クエリのタイムアウト

querier:
  query_timeout: 5m
  max_concurrent_queries: 20
診断コマンド
# Check pod status
kubectl get pods -n monitoring -l app.kubernetes.io/name=tempo

# Check distributor logs
kubectl logs -n monitoring -l app.kubernetes.io/component=distributor --tail=100

# Check ingester logs
kubectl logs -n monitoring -l app.kubernetes.io/component=ingester --tail=100

# Verify readiness
kubectl exec -it <tempo-pod> -n monitoring -- wget -qO- http://localhost:3200/ready

# Check ring status
kubectl port-forward svc/tempo-distributor 3200:3200 -n monitoring
curl http://localhost:3200/distributor/ring

API リファレンス

トレースの取得
# Get trace by ID
GET /api/traces/<traceID>

# Search traces (TraceQL)
GET /api/search?q={resource.service.name="api"}

# Search tags
GET /api/search/tags
GET /api/search/tag/<tag>/values
ヘルスチェック
GET /ready
GET /metrics

リファレンスドキュメント

トピック別の詳細な設定については、以下をご覧ください。

外部リソース


注意事項

  • 保持期間はテナントごとに設定されます。グローバルの保持期間はフォールバックにすぎず、テナントの設定を誤ると、気付かないまま上書きされます。
  • OTel コレクターのパイプライン末尾でのテールサンプリングでは、トレースがインフライトバッファーから解放されません。負荷が高いと、コレクターは破棄しようとしているトレースによってメモリ不足になります。
  • TraceQL の {} 式はクエリ文字列ではなくフィルター式です。PromQL/LogQL とは意味が異なるため、クエリパターンをコピーして貼り付けると、気付きにくい問題が発生します。
  • X-Scope-OrgID によるマルチテナント:ヘッダーが欠落している、または無効な場合は、Loki/Mimir と同様に「fake」テナントに割り当てられます。
  • スパンサイズの上限(デフォルトは 1 MB):上限を超えるスパンは、属性の途中で気付かないまま切り詰められます。discarded_spans_total の Ingester メトリクスを確認してデバッグしてください。
  • service.name と resource.service.name のどちらで検索するか:属性がスパンとリソースのどちらに設定されるかは、使用している OTel SDK によって異なります。どちらも似ていますが、インデックスの方法は異なります。

コメント