👻

Grafana Pyroscope を触ってみる

2024/07/18に公開

はじめに

Grafana Pyroscope を利用してプロファイルデータを可視化するまでの方法を紹介します。

https://grafana.com/docs/pyroscope

Grafana Pyroscope とは

Grafana Pyroscope とは、 Grafana Labs が開発しているプロファイリングツールです。
これにより、システムやアプリケーションのリソース使用状況に関する詳細なデータを収集し、可視化することができます。
Grafana のダッシュボードと連携することで、プロファイリングデータを効果的に視覚化し、問題の特定と解決をサポートします。

Grafana Pyroscope の構築

Grafana Pyroscope を迅速に構築するためには、 docker compose を用いるのが便利です。
以下に、 docker compose を用いた簡単な構築手順を紹介します。

Docker Compose ファイルの準備

まず、docker-compose.yml ファイルを作成します。以下の内容を含めてください。

services:
  pyroscope:
    image: grafana/pyroscope:latest
    ports:
      - "4040:4040"

このファイルを作成したら、以下のコマンドでコンテナを起動します。

docker compose up -d

これで Grafana Pyroscope の基本的な環境が整います。

Grafana Pyroscope へのプロファイルデータの書き込み

Grafana Pyroscope へのプロファイルデータの書き込みには 2 種類の方法があります。
対象のアプリケーションが pprof 形式のエンドポイントを提供している場合は、そのエンドポイントにアクセスすることでデータを収集する pull 形式が利用できます。
また、対象のアプリケーション内部に Grafana Pyroscope の SDK を組み込むことで、データを直接送信する push 形式も利用できます。

Pull

Kubernetes を利用してアプリケーションをデプロイしている場合は Grafana Pyroscope 側からプロファイルデータの収集を行うことができます。
https://grafana.com/docs/pyroscope/latest/deploy-kubernetes/helm/#optional-scrape-your-own-workloads-profiles

Pod の template に以下のようなアノテーションを追加することで、プロファイルデータの収集を行うことができます。
memory / cpu / goroutine にはプロファイルデータの種類を指定します。
指定できるプロファイルデータの種類は cpu / memory / goroutine / block / mutex となっています。

metadata:
  annotations:
    profiles.grafana.com/memory.scrape: "true"
    profiles.grafana.com/memory.port: "8080"
    profiles.grafana.com/cpu.scrape: "true"
    profiles.grafana.com/cpu.port: "8080"
    profiles.grafana.com/goroutine.scrape: "true"
    profiles.grafana.com/goroutine.port: "8080"

Push

Go での実装例を以下に示します。
アプリケーションの挙動としては、 1 秒ごとに "foo" という文字列を出力するだけのシンプルなものです。

アプリケーションの初期化時に pyroscope-go を利用してプロファイルデータの送信を開始します。
https://github.com/grafana/pyroscope-go

package main

import (
	"fmt"
	"time"

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

func main() {
	// Pyroscope の初期化
	pyroscope.Start(pyroscope.Config{
		ApplicationName: "sample",
		ServerAddress:   "http://localhost:4040",
		Logger:          pyroscope.StandardLogger, // 本番環境では無効化を推奨します
		UploadRate:      1 * time.Second,
		ProfileTypes:    pyroscope.DefaultProfileTypes,
	})
	// ここまで

	ticker := time.NewTicker(1 * time.Second)

	for {
		select {
		case <-ticker.C:
			fmt.Println("foo")
		}
	}
}

Loggerpyroscope.StandardLogger を指定するとデバッグログが出力されます。
プロファイルデータの送信の度にログが出力されるため、本番環境では無効化を推奨します。
Logger を指定しないことでログの出力を抑制することができます。

ProfileTypes は必要に応じて送信するプロファイルデータの種類を指定することができます。
デフォルトでは以下の 4 種類が利用可能です。
https://github.com/grafana/pyroscope-go/blob/f1a626fc4fe02866a4c37bd52814506fa9cf78cf/types.go#L28-L34

利用可能な全てのプロファイルデータの種類は以下のリンクから確認できます。
https://github.com/grafana/pyroscope-go/blob/f1a626fc4fe02866a4c37bd52814506fa9cf78cf/types.go#L15-L24

Grafana Pyroscope での動作確認

http://localhost:4040 にアクセスすることでアプリケーションから送信されたプロファイルデータを確認することができます。

最後に

Grafana Pyroscope を利用することで、アプリケーションのリソース使用状況に関する詳細なデータを収集し、可視化することができます。

また、 Grafana Pyroscope SDK を利用することでプロファイルデータの送信間隔を自由に調整することができます。
これにより、瞬間的なアプリケーションの変化も可視化することができるようになります。

Discussion