mcpField
P
pyroscope

pyroscope

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

pyroscope について

Grafana Pyroscope Skillは、コードレベルでアプリケーション性能を調べるための継続的プロファイリング基盤の導入・利用ガイドです。複数言語のプロファイル収集、保存、検索、Grafana連携を扱います。

主な機能

  1. 01コードレベルの継続的なプロファイル収集
  2. 02複数言語とプロファイル種別への対応
  3. 03モノリシックとマイクロサービスの導入形態
  4. 04オブジェクトストレージの設定
  5. 05Grafanaでのメトリクス、ログ、トレースとの関連付け

活用シーン

  1. 01アプリケーションのCPUやメモリ消費の特定
  2. 02Kubernetesへのプロファイリングサービス導入
  3. 03プロファイルデータのオブジェクトストレージ保存
  4. 04トレースと併せたコード性能の分析

インストール

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

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

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

同梱ファイル

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

references/
architecture.md
helm-deployment.md
sdk-instrumentation.md
troubleshooting.md

詳細

Grafana Pyroscope スキル

Grafana Pyroscope の包括的なガイドです。コードレベルでアプリケーションのパフォーマンスを分析する、オープンソースの継続的プロファイリングプラットフォームです。

Pyroscope とは?

Pyroscope は、次の特長を備えた水平スケーラブルで高可用性のマルチテナント継続的プロファイリングシステムです。

  • 最小限のオーバーヘッド(CPU の約 2~5%)でプロファイリングデータを継続的に収集します
  • ソースコードの行単位の粒度でコードレベルの可視性を提供します
  • 圧縮したプロファイルをオブジェクトストレージ(S3、GCS、Azure Blob)に保存します
  • Grafana と統合し、プロファイルをメトリクス、ログ、トレースと関連付けます
  • 複数の言語に対応しています。Go、Java、Python、.NET、Ruby、Node.js、Rust

アーキテクチャの概要

コアコンポーネント
コンポーネント目的
Distributor受信したプロファイルを検証し、Ingester にルーティングします
Ingesterプロファイルをメモリにバッファリングし、圧縮してストレージに書き込みます
Querier分析のためにプロファイルデータを取得して処理します
Query Frontendクエリリクエスト、キャッシュ、スケジューリングを処理します
Query Schedulerテナントごとのクエリキューを管理します
Store Gateway長期プロファイルストレージへのアクセスを提供します
Compactorブロックをマージし、保持期間を管理して、削除を処理します
データフロー

書き込みパス:

SDK/Alloy → Distributor → Ingester → Object Storage
                                   ↓
                             Blocks + Indexes

読み取りパス:

Query → Query Frontend → Query Scheduler → Querier
                                             ↓
                                    Ingesters + Store Gateway

デプロイモード

1. モノリシックモード(-target=all)
  • すべてのコンポーネントが単一のプロセスで動作します
  • 最適な用途:開発、小規模なデプロイ
  • クエリ URL:http://pyroscope:4040/
2. マイクロサービスモード(本番環境)
  • 各コンポーネントが独立して動作します
  • 水平スケーラブルです
  • クエリ URL:http://pyroscope-querier:4040/
# Microservices deployment
architecture:
  microservices:
    enabled: true

querier:
  replicas: 3
distributor:
  replicas: 2
ingester:
  replicas: 3
compactor:
  replicas: 3
storeGateway:
  replicas: 3

クイックスタート - Kubernetes Helm

リポジトリを追加
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
シングルバイナリをインストール
kubectl create namespace pyroscope
helm install pyroscope grafana/pyroscope -n pyroscope
マイクロサービスモードをインストール
curl -Lo values-micro-services.yaml \
  https://raw.githubusercontent.com/grafana/pyroscope/main/operations/pyroscope/helm/pyroscope/values-micro-services.yaml

helm install pyroscope grafana/pyroscope \
  -n pyroscope \
  --values values-micro-services.yaml

プロファイルの種類

種類説明言語
CPUウォール時間/CPU 時間の消費量すべて
Memory割り当てオブジェクト/スペース、ヒープGo、Java、.NET
Goroutine並行実行される goroutineGo
Mutexロック競合(回数/時間)Go、Java、.NET
Blockスレッドのブロック/遅延Go
Exceptions例外の追跡Python

クライアントの設定方法

方法 1:SDK によるインストルメンテーション(プッシュモード)

Go SDK:

import "github.com/grafana/pyroscope-go"

pyroscope.Start(pyroscope.Config{
    ApplicationName: "my-app",
    ServerAddress:   "http://pyroscope:4040",
    ProfileTypes: []pyroscope.ProfileType{
        pyroscope.ProfileCPU,
        pyroscope.ProfileAllocObjects,
        pyroscope.ProfileAllocSpace,
        pyroscope.ProfileInuseObjects,
        pyroscope.ProfileInuseSpace,
        pyroscope.ProfileGoroutines,
        pyroscope.ProfileMutexCount,
        pyroscope.ProfileMutexDuration,
        pyroscope.ProfileBlockCount,
        pyroscope.ProfileBlockDuration,
    },
    Tags: map[string]string{
        "env": "production",
    },
})

Java SDK:

PyroscopeAgent.start(
    new Config.Builder()
        .setApplicationName("my-app")
        .setServerAddress("http://pyroscope:4040")
        .setProfilingEvent(EventType.ITIMER)
        .setFormat(Format.JFR)
        .build()
);

Python SDK:

import pyroscope

pyroscope.configure(
    application_name="my-app",
    server_address="http://pyroscope:4040",
    tags={"env": "production"},
)
方法 2:Grafana Alloy(プルモード)

アノテーションによる自動インストルメンテーション:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    metadata:
      annotations:
        profiles.grafana.com/cpu.scrape: "true"
        profiles.grafana.com/cpu.port: "8080"
        profiles.grafana.com/memory.scrape: "true"
        profiles.grafana.com/memory.port: "8080"
        profiles.grafana.com/goroutine.scrape: "true"
        profiles.grafana.com/goroutine.port: "8080"

Alloy の設定:

pyroscope.scrape "default" {
  targets = discovery.kubernetes.pods.targets
  forward_to = [pyroscope.write.default.receiver]

  profiling_config {
    profile.process_cpu { enabled = true }
    profile.memory { enabled = true }
    profile.goroutine { enabled = true }
  }
}

pyroscope.write "default" {
  endpoint {
    url = "http://pyroscope:4040"
  }
}
方法 3:eBPF プロファイリング(Linux)

コンパイル言語(C/C++、Go、Rust)向け:

pyroscope.ebpf "default" {
  forward_to = [pyroscope.write.default.receiver]
  targets = discovery.kubernetes.pods.targets
}

ストレージの設定

Azure Blob Storage
pyroscope:
  config:
    storage:
      backend: azure
      azure:
        container_name: pyroscope-data
        account_name: mystorageaccount
        account_key: ${AZURE_ACCOUNT_KEY}
AWS S3
pyroscope:
  config:
    storage:
      backend: s3
      s3:
        bucket_name: pyroscope-data
        region: us-east-1
        endpoint: s3.us-east-1.amazonaws.com
        access_key_id: ${AWS_ACCESS_KEY_ID}
        secret_access_key: ${AWS_SECRET_ACCESS_KEY}
Google Cloud Storage
pyroscope:
  config:
    storage:
      backend: gcs
      gcs:
        bucket_name: pyroscope-data
        # Uses GOOGLE_APPLICATION_CREDENTIALS

Grafana との統合

データソースの設定
apiVersion: 1
datasources:
  - name: Pyroscope
    type: grafana-pyroscope-datasource
    access: proxy
    url: http://pyroscope-querier:4040
    isDefault: false
    editable: true
トレースからプロファイルへのリンク

スパンプロファイルを有効にすると、トレースをプロファイルと関連付けられます。

OpenTelemetry を使用した Go:

import (
    "github.com/grafana/pyroscope-go"
    otelpyroscope "github.com/grafana/otel-profiling-go"
)

tp := trace.NewTracerProvider(
    trace.WithSpanProcessor(otelpyroscope.NewSpanProcessor()),
)

要件:

  • スパンの最小継続時間:20ms
  • 対応言語:Go、Java、.NET、Python、Ruby

リソース要件

シングルバイナリ(開発)
resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 1
    memory: 2Gi
マイクロサービス(本番環境)
コンポーネントCPU リクエストメモリリクエストメモリ制限
Distributor500m256Mi1Gi
Ingester18Gi16Gi
Querier100m256Mi1Gi
Query Frontend100m256Mi1Gi
Compactor18Gi16Gi
Store Gateway18Gi16Gi

Helm の一般的な値

# Production values
architecture:
  microservices:
    enabled: true

pyroscope:
  persistence:
    enabled: true
    size: 50Gi

  config:
    storage:
      backend: s3
      s3:
        bucket_name: pyroscope-prod
        region: us-east-1

# High availability
ingester:
  replicas: 3
  terminationGracePeriodSeconds: 600

querier:
  replicas: 3

distributor:
  replicas: 2

compactor:
  replicas: 3
  terminationGracePeriodSeconds: 1200

storeGateway:
  replicas: 3

# Pod disruption budget
podDisruptionBudget:
  enabled: true
  maxUnavailable: 1

# Topology spread
topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule

# Monitoring
serviceMonitor:
  enabled: true

# Alloy for profile collection
alloy:
  enabled: true

API エンドポイント

取り込み
# Push profiles (Connect API)
POST /push.v1.PusherService/Push

# Legacy HTTP (pprof, JFR formats)
POST /ingest
クエリ
# Merged profile
POST /querier.v1.QuerierService/SelectMergeProfile

# Flame graph data
POST /querier.v1.QuerierService/SelectMergeStacktraces

# Available labels
POST /querier.v1.QuerierService/LabelNames

# Profile types
POST /querier.v1.QuerierService/ProfileTypes

# Legacy render
GET /pyroscope/render?query={}&from=now-1h&until=now
システム
# Readiness
GET /ready

# Configuration
GET /config

# Metrics
GET /metrics

トラブルシューティング

診断コマンド
# Check pod status
kubectl get pods -n pyroscope -l app.kubernetes.io/name=pyroscope

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

# Check ring status
kubectl exec -it pyroscope-0 -n pyroscope -- \
  curl http://localhost:4040/ingester/ring

# Verify readiness
kubectl exec -it pyroscope-0 -n pyroscope -- \
  curl http://localhost:4040/ready

# Check configuration
kubectl exec -it pyroscope-0 -n pyroscope -- \
  curl http://localhost:4040/config
よくある問題

1. Ingester の OOM:

ingester:
  resources:
    limits:
      memory: 16Gi

2. ストレージの認証失敗:

# Azure - verify RBAC
az role assignment create \
  --role "Storage Blob Data Contributor" \
  --assignee-object-id <principal-id> \
  --scope <storage-scope>

3. カーディナリティの高いラベル:

# Limit label cardinality
pyroscope:
  config:
    validation:
      max_label_names_per_series: 25

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

pyroscope:
  config:
    querier:
      query_timeout: 5m
      max_concurrent: 8

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

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

外部リソース


注意点

  • アプリケーションごとのプロファイルサンプリングレート:負荷の高いサービスでは、100Hz にすると無視できないオーバーヘッドが発生します。まずカナリアでプロファイリングしてください。
  • ストレージのコンパクション中はマージ処理によって新しい書き込みがブロックされます:大規模なコンパクションは書き込みの停滞を引き起こすため、チャンクサイズとコンパクションウィンドウの調整が必要です。
  • タグのカーディナリティの爆発:リクエストごとのタグはストレージを膨張させます。タグ値に明示的な上限を設けないと、ストレージは毎週倍増します。
  • トレース連携:スパンとプロファイルのリンクには、エンドツーエンドで traceparent ヘッダーが伝播される必要があります。計装されていないホップが1つでもあると、リンクは通知なく失われます。
  • eBPF プロファイラーと SDK プロファイラー:アトリビューションが異なり、競合する場合もあります。同じサービスで両方を実行しないでください。
  • gRPC と HTTP プッシュ:データは同じですが、インジェスターでのレート制限が異なります。負荷がかかると、HTTP プッシュのほうが強くスロットリングされます。

コメント