Grafana + Prometheusの最小構成における基本機能を網羅的かつ分かりやすく解説

# はじめに

システム監視や機械学習モデルの推論状況を見える化したい場面は多いですが、専用の監視基盤を用意するにはハードルが高いこともあります。特に、開発初期の小さな構成で「とりあえず動かして状態を可視化したい」ニーズは根強いです。

そこで登場するのが **Prometheus** + **Grafana** の組み合わせです。Prometheusはメトリクス収集・監視のためのツールであり、Grafanaはそのデータを可視化するダッシュボードです。本記事では、最小限の構成でこれらを動かし、基本機能を学ぶことを目指します。

# 簡易な構成図
簡単な処理の流れは以下の通りです
```
[FastAPI]──┐
           │             +-----------+
[NodeExporter]───▶ [Prometheus] ──▶ [Grafana]
           │             +-----------+
           ▼
        /metrics
```

ディレクトリ構成は以下の通りです
```
project-root/
├── docker-compose.yml
├── prometheus/
│   └── prometheus.yml
│   └── alert.rules.yml
├── grafana/
│   └── provisioning/
├── fastapi/
│   └── app.py（Prometheusメトリクスを返す）
```

```yml:docker-compose.yml
version: '3'

services:
  fastapi:
    build: ./fastapi
    ports:
      - "8000:8000"
    volumes:
      - ./fastapi:/app
    depends_on:
      - mlflow
    environment:
      - MLFLOW_TRACKING_URI=http://mlflow:5010

  mlflow:
    build: ./mlflow
    ports:
      - "5010:5010"
    volumes:
      - ./mlflow:/mlflow
      - mlflow_data:/mlflow/data
    environment:
      - MLFLOW_TRACKING_URI=http://mlflow:5010

  jupyter:
    build: ./jupyter
    ports:
      - "8888:8888"
    volumes:
      - ./jupyter:/jupyter
    depends_on:
      - mlflow
    environment:
      - MLFLOW_TRACKING_URI=http://mlflow:5010

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus:/etc/prometheus
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'
    depends_on:
      - fastapi
      - node-exporter

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    volumes:
      - ./grafana/provisioning:/etc/grafana/provisioning
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
    depends_on:
      - prometheus

  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"
    container_name: node-exporter

volumes:
  mlflow_data:
  prometheus_data:
  grafana_data:
```

# Prometheusの機能紹介
## 時系列の可視化

Prometheusは/metricsを定期的に収集（スクレイピング）し、保存した数値を時系列で可視化できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483926/26dc2310-52ab-45c0-9bf6-c56b87583038.png)

上記は例として、クエリは「model_predictions_total」を入力し、予測の呼ばれた回数を時系列で可視化しています。

## PromQLクエリについて
PromQL（Prometheus Query Language）を使って、以下のようなクエリが記述可能です：
- up：各ターゲットの稼働状況
- rate(http_requests_total[1m])：1分間のリクエストレート
- node_memory_MemAvailable_bytes：空きメモリの時系列変化

また、通常のクエリは以下のようなものがあります。
| クエリ名                               | 内容            |
| ---------------------------------- | ------------- |
| `model_predictions_total`          | 予測が何回呼ばれたか    |
| `prediction_latency_seconds_count` | 推論回数（レイテンシ付き） |
| `prediction_latency_seconds_sum`   | 推論にかかった合計時間   |
| `prediction_value`                 | 直近の予測値（あれば）   |
| `prediction_errors_total`          | エラー回数         |
| `prediction_error_type_total`      | エラーの種類ごとの回数   |


例：
rate(model_predictions_total[1m])は、直近1分のリクエスト回数を可視化することが可能です。

## アラートの設定
alert.rules.yml に以下のようなルールを書き、Prometheusに読み込ませることでアラートを設定できます：
```yml:alert.rules.yml
groups:
  - name: fastapi_alerts
    rules:
      - alert: HighPredictionErrorRate
        expr: rate(prediction_errors_total[1m]) > 0.1
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "Prediction error rate is high"
          description: "More than 0.1 errors/sec in the last 1 minute"
```

Prometheusの Alerts タブで発火状況を確認できます。

# Grafanaの機能紹介
## データソース設定
Data Sources → Add data source → Prometheusを選択し、URLにhttp://prometheus:9090 を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483926/39f25363-c0c5-49bc-9d4e-171cb56a6f55.png)

## ダッシュボード作成
Dashboard → Add new panel → 任意のクエリを入力を行うことで、クエリの情報を可視化したダッシュボードを作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483926/d11ab1d3-e802-432c-9481-790fbc146d68.png)


キャプチャのものは、上の図は時系列でのエラー発生回数、下の図は該当APIへのリクエスト数を時系列に可視化したものです。

## アラートの設定
画面左のalert ruleリンクをクリックすることで設定が可能。
アラートルールを設定し、ダッシュボードにアラート発生状況を可視化することが可能。

#### Prometheusのアラート機能とGrafanaのアラート機能の違い
Prometheusのアラート機能とGrafanaのアラート機能は似ているようで、目的や使い方に違いがあります。
簡単に機能を比較しました。
| 比較項目         | Prometheus（+ Alertmanager）                       | Grafana |
| ------------ | ------------------------------------------------ | ----------------------------------------- |
| アーキテクチャ   | サーバサイドで動作、Alertmanagerと連携が前提                     | Grafana単体で完結する（通知機能も内蔵）                   |
| 通知先       | Slack, Email, PagerDuty, Webhook（Alertmanager経由） | Slack, Discord, Teams, Webhook などGUIで簡単設定 |
| アラート条件の対象 | PromQLクエリに基づくメトリクス全体（ダッシュボードとは無関係）               | ダッシュボード上の「パネル」に紐づく条件ベース                   |
| 管理方法      | `alert.rules.yml` にYAMLで定義（コード管理しやすい）            | UIから簡単に作成・可視化（非エンジニアも扱える）                 |
| 再利用性      | モニタリング環境全体で共通利用                                  | 個別の視覚化に依存しやすい                             |
| 可視化との連携   | アラート結果は別途見に行く必要あり                                | ダッシュボードと同じ場所に表示できる                        |

整理すると、以下がおすすめと考えています。
| 用途                                        | おすすめ                                     |
| ----------------------------------------- | ---------------------------------------- |
| モデル推論の失敗やレイテンシを**定期監視＋Slack通知**したい        |  **Prometheus + Alertmanager**（運用監視に強い） |
| Grafanaで**個別のグラフにしきい値を設定し、GUIで即確認・通知**したい |  **Grafanaアラート**（視覚・直感的な運用に向く）          |
| チームで**コードベースで管理し、CI/CDに組み込みたい**           | Prometheus側（IaCに強い）                    |
| 非エンジニアが**GUIから条件を柔軟に設定したい**               | Grafana側                               |


## よく使うクエリ・可視化例

| クエリ名                               | 説明            |
| ---------------------------------- | ------------- |
| `up`          | 各サービスの生存チェック |
| `rate(model_predictions_total[1m])`          | 推論APIの1分間あたりのリクエスト数    |
| `prediction_value` | 最新の予測値 |
| `rate(prediction_errors_total[1m])` | エラー発生頻度|
| `rate(node_cpu_seconds_total{mode!="idle"}[1m])` | CPU使用率|


# 終わりに
Prometheus + Grafana の最小構成を使えば、軽量で柔軟な監視環境をすぐに立ち上げることが可能です。
今後の発展編では以下のようなテーマに取り組むとより便利な環境となります：
- Slack/メール連携を含む Alertmanagerの導入
- 複数Exporter構成（Blackbox Exporter, Pushgatewayなど）
- Grafanaでの自動テンプレート管理（provisioning）