前回の記事では、.NET Web API のトレース情報を取得し、Jaeger を使って可視化する方法を紹介しました。今回はその続編として、アプリケーションのメトリクスを収集し、Prometheus と Grafana を用いて可視化する手順を解説します。
環境
以下の環境で動作確認を行っています。
os | windows11(4cpu、16GB) |
.NET | 8.0.304 |
IDE | Visual Studio 2022 Community |
Jaeger(コンテナ) | 2.8.0 |
Docker | 28.3.0 |
記事のコードは、解説をわかりやすくするために、エラーチェックなど一部の処理を省略しています。
OpenTelemetryの設定
ASP.NET Core Web API プロジェクトにメトリクスを出力するための設定を行います。
まずは以下のライブラリを NuGet 経由でインストールしてください。
パッケージ名 | 概要 |
---|---|
OpenTelemetry.Extensions.Hosting (1.12.0) | DI(依存関係注入)を通じた OpenTelemetry の構成用拡張ライブラリ |
OpenTelemetry.Instrumentation.AspNetCore (1.12.0) | ASP.NET Core のリクエスト処理(受信)に関するメトリクスを出力 |
OpenTelemetry.Instrumentation.Http (1.12.0) | HttpClient による外部リクエスト(送信)に関するメトリクスを出力 |
OpenTelemetry.Exporter.Prometheus.AspNetCore (1.12.0-beta.1) | Prometheus用のエンドポイントを構成するためのライブラリ。※ベータ版 |
Npgsql.OpenTelemetry (9.0.3) | PostgreSQL(Npgsql)に関するメトリクスを出力 |
メトリクスの出力設定
Program.cs に以下の設定を追加します。Instrumentation メソッドにより、自動的にメトリクスを取得できるようになります。また、Prometheus に対応するため AddPrometheusExporter と app.UseOpenTelemetryPrometheusScrapingEndpoint を追加します。これにより、Prometheusがメトリクスをスクレイピングするためのエンドポイントを構築できます。
builder.Services.AddOpenTelemetry()
.ConfigureResource(r => r.AddService(builder.Environment.ApplicationName))
.WithMetrics(m => m
.AddAspNetCoreInstrumentation()
.AddNpgsqlInstrumentation()
.AddHttpClientInstrumentation()
.AddPrometheusExporter()
);
(略)
app.UseOpenTelemetryPrometheusScrapingEndpoint();
また以下の設定を行います。デフォルトではHTTPリクエストはHTTPSにリダイレクトされます。Prometheusがローカル実行しているアプリのエンドポイントにアクセスできるように、開発環境の場合にリダイレクト機能を外します。あくまで開発環境だけの一時的な設定です(詳細な理由は後述)。
if (!app.Environment.IsDevelopment())
{
app.UseHttpsRedirection();
}
確認
アプリを実行すると、コンソール上に Prometheus 用のエンドポイント URL(例:http://localhost:5139/metrics)が表示されます。この URL にブラウザでアクセスし、メトリクスが表示されれば成功です。


リダイレクトを無効にしていない場合は、https://localhost:7027にリダイレクトされます。
OSSツールの設定(Prometheus / Grafana)
PrometheusとGrafanaをDockerで起動させます。
Prometheus
以下の内容で docker-compose.yml を作成します。設定ファイルをバインドするため ./config ディレクトリを作成します。
services:
prometheus:
image: prom/prometheus:main
container_name: prometheus
volumes:
- ./config:/etc/prometheus
ports:
- "9090:9090"
restart: unless-stopped
config/prometheus.yml の内容は以下のとおりです。
scrape_configs:
- job_name: "prometheus"
scrape_interval: 10s
static_configs:
- targets: ["host.docker.internal:5139"]
コンテナ内からlocalhost:5139にアクセスしても、ホストOSで実行されているPrometheus用エンドポイントにはアクセスできません。そこで、コンテナからホストにアクセスするためのドメインとして用意されている「host.docker.internal」を利用します。
コンテナを docker compose up -d で起動させたらlocalhost:9090にアクセスします。その後、「Status > Target health」を確認して、エンドポイントのStateがUPであれば成功です。

Grafana
Prometheus に続いて、Grafana の設定を行います。docker-compose.yml に以下を追加します。通常はデータの永続化を行うためにストレージやローカルディレクトリへのバインド設定を行いますが、本記事では説明を簡略化するため省略しています(Prometheusも同様)。
grafana:
image: grafana/grafana:main-ubuntu
container_name: grafana
depends_on:
- prometheus
ports:
- "3000:3000"
restart: unless-stopped
localhost:3000 にアクセスし、初期 ID/Password(admin/admin)でログインします。パスワード変更後、Data Sources > Add Data Source > Prometheus を選択し、以下のように設定します:
URL:http://prometheus:9090 (← Docker Compose 上のサービス名を指定)

これで Grafana 上でメトリクスを可視化できるようになります。ダッシュボードを作成して好きなクエリをグラフ化しましょう。

おまけ
Grafana ではトレース情報も扱うことが可能です。Data Source に Jaeger を追加すれば、Explore タブからトレース情報を確認できます。Prometheus と Jaeger を同じダッシュボードから参照できるのは非常に便利です。

まとめ
.NET アプリケーションのパフォーマンスを定量的に把握するには、トレースとあわせてメトリクスの可視化が重要です。OpenTelemetry は最小限の設定でこれを実現できる強力なツールであり、Prometheus + Grafana との組み合わせはローカル開発環境でも簡単に導入可能です。
コメント