Chillarin Blog 構成紹介 - 8.監視基盤編 Part3(ダッシュボード設計と運用知見)-
Grafanaダッシュボードの設計方針と、自宅サーバを半年以上運用して得た監視の知見。「見るべきもの」と「見なくていいもの」の線引き。
はじめに
Part1(設計思想と全体像)で「何を監視するか」、Part2(構築手順編)で「どう構築するか」を紹介しました。
最終回の Part3 では、Grafana ダッシュボードの設計 と、実際に半年以上運用してみてわかった 「見るべきメトリクス」「見なくていいメトリクス」 の話をします。
正直、監視は「入れた直後」が一番モチベーション高くて、気づいたらダッシュボードを開かなくなる……というのが自宅サーバあるある。 どうすれば「開き続けるダッシュボード」になるのか、自分なりの答えを書いてみます。
ダッシュボード設計の方針
最初に結論を言うと、ダッシュボードは 3枚 に絞っています。
| # | 名前 | 目的 | 見る頻度 |
|---|---|---|---|
| 1 | Overview | 全ホスト・全コンテナの健康状態を一目で | 毎日(朝のルーティン) |
| 2 | Blog Analytics | ブログのアクセス状況 + Cloudflare 統計 | 週1〜2回 |
| 3 | Troubleshoot | トラブル発生時のメトリクス + ログ横断 | 問題が起きた時だけ |
最初は「ホスト用」「コンテナ用」「nginx用」「ログ用」…… と分けて7〜8枚作ったんですが、結局見なくなりました。 ダッシュボードが増えるほど「どこを見ればいいかわからない」という本末転倒な状態になります。
今は 「毎日見る1枚」+「たまに見る1枚」+「消火活動用1枚」 の3枚構成に落ち着いています。
Dashboard 1: Overview(毎日見るやつ)
このダッシュボードの設計思想は 「10秒で全体の健康状態がわかる」 です。
構成
上から順に、こういうレイアウトにしています。
┌────────────────────────────────────────────────────────────┐
│ [Stat] ホスト稼働数 [Stat] コンテナ稼働数 [Stat] アラート数 │
├────────────────────────────────────────────────────────────┤
│ │
│ [Table] ホスト一覧 │
│ ┌──────────────┬───────┬────────┬────────┬──────────┐ │
│ │ ホスト │ CPU │ メモリ │ ディスク │ 稼働時間 │ │
│ ├──────────────┼───────┼────────┼────────┼──────────┤ │
│ │ chillarin-sv01│ 12% │ 68% │ 42% │ 45d 3h │ │
│ │ nuc1 │ 3% │ 24% │ 23% │ 90d 12h │ │
│ │ nuc2 │ 5% │ 52% │ 31% │ 90d 12h │ │
│ │ nuc3 │ 1% │ 6% │ 15% │ 90d 12h │ │
│ └──────────────┴───────┴────────┴────────┴──────────┘ │
│ │
├────────────────────────────────────────────────────────────┤
│ │
│ [Table] コンテナ一覧 │
│ ┌──────────────┬────────┬────────┬──────────┬───────────┐ │
│ │ コンテナ │ 状態 │ CPU │ メモリ │ リスタート │ │
│ ├──────────────┼────────┼────────┼──────────┼───────────┤ │
│ │ nginx │ ✅ Up │ 0.3% │ 45MB │ 0 │ │
│ │ hugo-blog │ ✅ Up │ 0.1% │ 12MB │ 0 │ │
│ │ cloudflared │ ✅ Up │ 0.2% │ 32MB │ 0 │ │
│ │ remark42 │ ✅ Up │ 0.5% │ 85MB │ 0 │ │
│ │ prometheus │ ✅ Up │ 1.2% │ 1.8GB │ 0 │ │
│ │ grafana │ ✅ Up │ 0.8% │ 210MB │ 0 │ │
│ │ loki │ ✅ Up │ 0.4% │ 320MB │ 0 │ │
│ └──────────────┴────────┴────────┴──────────┴───────────┘ │
│ │
├────────────────────────────────────────────────────────────┤
│ [Time Series] ディスク使用量推移(7日間) │
│ │
│ 100% ─ │
│ 80% ─ - - - - - - - - - - - - - ← アラートライン │
│ 60% ─ │
│ 40% ─ ═══════════════════ sv01 │
│ 20% ─ ──────────────── nuc1 │
│ 0% ─┬──────┬──────┬──────┬──────┬──────┬──────┬─ │
│ 月 火 水 木 金 土 日 │
│ │
└────────────────────────────────────────────────────────────┘なぜこの構成か
Stat パネル(最上段) は「異常があるかないか」を0.5秒で判定するためのもの。 全部緑なら平和。赤いのがあったら下を見る。 これだけのために開く価値があります。
ホスト一覧テーブル はメトリクスを横に並べて比較するため。 パネルを個別に作るとスクロールが必要になって一覧性が下がるので、テーブル1つにまとめています。
ここで一番大事なのは ディスク使用率の列。 これだけは色分け(Threshold)を入れていて、70%超で黄色、85%超で赤になります。
コンテナ一覧テーブル はリスタート回数に注目しています。 リスタートが0以外のコンテナは、何かしら問題を抱えている可能性が高い。 OOM killer で殺されて自動復帰しているケースが多いです。
ディスク使用量の推移グラフ は「トレンド」を見るためのもの。 瞬間値よりも「1週間でどれくらい増えたか」が重要です。 直線的に増えていたらログかDockerイメージが溜まっている証拠なので、掃除する必要があります。
設計のコツ: PromQL をシンプルに保つ
Grafana のパネルに入れる PromQL は、できるだけシンプルにしています。 1つのパネルで複雑なクエリを組み合わせすぎず、CPU、メモリ、ディスクをそれぞれ独立したシンプルなクエリで取って、テーブルの各列に割り当てる方がメンテしやすいです。
📦 Overview ダッシュボードで使用している PromQL クエリの全量(ホスト一覧テーブル・コンテナ一覧テーブル・ディスク推移グラフ)は 有料コンテンツ: 自宅サーバ構築シリーズ に含まれています。
Dashboard 2: Blog Analytics(週1〜2回見るやつ)
このダッシュボードはブログの運営指標を見るためのものです。
構成
┌─────────────────────────────────────────────────────────┐
│ [Stat] 今日のPV [Stat] 今週のPV [Stat] 月間PV │
├──────────────────────────┬──────────────────────────────┤
│ │ │
│ [Time Series] │ [Pie Chart] │
│ 日別PV推移(30日間) │ アクセス元 国別内訳 │
│ │ │
├──────────────────────────┴──────────────────────────────┤
│ │
│ [Bar Gauge] 記事別PV ランキング TOP10 │
│ │
├─────────────────────────────────────────────────────────┤
│ [Stat] キャッシュヒット率 [Stat] 帯域使用量 │
├─────────────────────────────────────────────────────────┤
│ [Time Series] nginx リクエスト数 + ステータスコード別 │
│ (200 / 301 / 304 / 404 / 5xx) │
└─────────────────────────────────────────────────────────┘データソースの使い分け
| メトリクス | ソース | 更新間隔 |
|---|---|---|
| PV / 国別 / キャッシュ率 | Cloudflare Exporter → Prometheus | 5分 |
| 記事別PV | Cloudflare Analytics API → Prometheus | 5分 |
| リクエスト数 / ステータスコード | nginx-exporter → Prometheus | 15秒 |
Cloudflare Analytics から取れるデータと nginx から取れるデータは微妙に違います。 Cloudflare 側はキャッシュヒットしたリクエストも含む「総PV」、nginx 側はオリジンまで到達したリクエストだけ。 ブログのPVを知りたいなら Cloudflare 側、サーバの負荷を知りたいなら nginx 側を見るのが正しいです。
📦 Blog Analytics ダッシュボードで使用している PromQL クエリの全量(Cloudflare Exporter 連携・nginx ステータスコード別集計)は 有料コンテンツ: 自宅サーバ構築シリーズ に含まれています。
運用してわかったこと: 404 を監視する価値
正直、PV数は毎日見なくてもいいんですが、404 の推移は見る価値があることがわかりました。
ある日突然 404 が急増して調べたら、記事のURLを変更した時に古いURLからのリダイレクトを入れ忘れていたことがありました。 Google のクローラが古いURLを叩いて 404 を大量に返していた、というオチ。
これに気づけたのは nginx-exporter でステータスコード別のリクエスト数を見ていたからです。 Hugo のパーマリンク変更時には必ず aliases を入れる ── という運用ルールがここから生まれました。
Dashboard 3: Troubleshoot(消火活動用)
このダッシュボードは普段使いません。 「なんかおかしい」時に開いて、メトリクスとログを横断して原因を掘る用。
構成のポイント
他の2枚と違って、Variables(テンプレート変数) を多用しています。
変数: $host = chillarin-sv01 | nuc1 | nuc2 | nuc3
変数: $container = nginx | hugo-blog | remark42 | cloudflared | ...
変数: $timerange = (Grafana デフォルトの時間範囲ピッカー)上部のドロップダウンでホストやコンテナを切り替えると、全パネルが連動して絞り込まれます。
レイアウト
┌─────────────────────────────────────────────────────────┐
│ [$host ▼] [$container ▼] [時間範囲ピッカー] │
├───────────────────────────┬─────────────────────────────┤
│ │ │
│ [Time Series] │ [Time Series] │
│ CPU使用率(5分平均) │ メモリ使用率 │
│ │ │
├───────────────────────────┼─────────────────────────────┤
│ │ │
│ [Time Series] │ [Time Series] │
│ ディスクI/O (read/write) │ ネットワーク (in/out) │
│ │ │
├───────────────────────────┴─────────────────────────────┤
│ │
│ [Logs Panel - Loki] │
│ $host + $container のログ(リアルタイム / tail モード) │
│ │
│ 2026-03-30 03:15:22 [nginx] 172.16.1.100 GET /... 200 │
│ 2026-03-30 03:15:23 [nginx] 172.16.1.100 GET /... 304 │
│ 2026-03-30 03:15:25 [remark42] level=error msg=... │
│ ... │
│ │
└─────────────────────────────────────────────────────────┘メトリクスとログが同じ時間軸で並んでいる のがこのダッシュボードの価値です。
例えば「3時頃に CPU が跳ねた」とわかったら、同じ時間範囲でログパネルを見て、その時間帯に何が起きていたかを確認できる。 別のツールを開いてタイムスタンプを手動で合わせる手間がないので、原因特定が格段に速くなります。
📦 Troubleshoot ダッシュボードで使用している PromQL / LogQL クエリの全量(テンプレート変数の定義・ログフィルタリング設定含む)は 有料コンテンツ: 自宅サーバ構築シリーズ に含まれています。
半年運用してわかった知見
1. 「見なくていいメトリクス」を決めるのが大事
監視を始めると「せっかくだからあれもこれも見たい」ってなりますが、90%のメトリクスは平常時に見ても何も得るものがありません。
見なくていいと判断したもの:
| メトリクス | 見なくていい理由 |
|---|---|
| CPU使用率(平常時) | 自宅サーバのCPUが常時50%を超えることはまずない |
| ネットワーク帯域(平常時) | Cloudflare がキャッシュしてくれるのでオリジンの帯域はスカスカ |
| 個々のコンテナのCPU | コンテナ単体で高負荷になるケースがほぼない |
| ファイルディスクリプタ数 | デフォルト上限で困ったことがない |
逆に、見続けて正解だったもの:
| メトリクス | 見ていて良かった理由 |
|---|---|
| ディスク使用率の 推移 | 「急に増えた」タイミングで原因を特定できた |
| コンテナのリスタート回数 | 夜中にOOMで再起動していたremark42を発見 |
| blackbox_exporter の成功率 | Cloudflare Tunnel の不安定さに気づけた |
| 404 の推移 | URL変更時のリダイレクト漏れを検知 |
2. アラートは少ないほどいい
Part1 でも書きましたが、運用して改めて感じたのは 「通知は4つで十分」 ということ。
最初は10個くらいアラートを設定していましたが、「CPU使用率が一瞬80%超えた」みたいな通知が来るたびに Discord を確認して「あ、別にいいやつだ」で閉じる ── という無駄が発生していました。 これが続くと通知を無視するようになって、本当に大事なアラートも見逃すようになります。
最終的に残したアラート(再掲):
- HostDiskAlmostFull(85%超)
- ContainerDown(主要コンテナが5分以上停止)
- HighMemoryUsage(90%超が10分以上)
- BlogUnreachable(外形監視3回連続失敗)
この4つ以外は全部切りました。 「通知が来たら必ず対処する」という状態を維持するのが最も大事です。
3. Grafana を「朝のルーティン」に組み込む
ダッシュボードは作っただけでは見なくなります。 自分の場合、朝コーヒーを入れながら Overview ダッシュボードを10秒眺める、というのを習慣にしています。
Grafana にはキオスクモードがあって、ブラウザでフルスクリーン表示にするとヘッダーやメニューが消えて数値だけが見えるようになります。 タブレットに常時表示する人もいるみたいですが、自分はそこまではやっていません。 ブラウザのブックマークバーに入れておいて、朝開くだけで十分。
4. ログは「全部保存」しなくていい
Loki でログを集約し始めると「せっかくだから全部保存したい」ってなりますが、これは罠です。
nginx のアクセスログだけで 1日 500MB くらいになるので、30日保持だと 15GB。 それに Docker コンテナのログや syslog を足すと、すぐに数十GBになります。
自分の運用では以下のルールにしています。
| ログ | 保持期間 | 理由 |
|---|---|---|
| nginx アクセスログ | 14日 | トラブルシュートには2週間で十分 |
| nginx エラーログ | 30日 | エラーは長めに残したい |
| Docker コンテナログ | 7日 | 大量に出るので短め |
| syslog | 30日 | カーネルパニックやOOMの記録は残す |
Loki 側の retention_period はグローバル設定なので、ログの種類別に保持期間を変えたい場合は limits_config の per_stream_rate_limit やラベルベースの retention ルールを使います。
ただし、自宅サーバでそこまで凝る必要があるかというと微妙なので、自分は全部 30日統一にして、ディスク使用量を注視する運用にしています。
5. 監視の監視は忘れがち
これは地味に大事な話。 Prometheus 自体が落ちたら、アラートが来ない んですよね。
対策として、blackbox_exporter で Grafana のヘルスチェックエンドポイント (/api/health) を監視しています。
……ただし、blackbox_exporter も chillarin-sv01 上で動いているので、chillarin-sv01 ごと落ちたら同じことです。
本格的にやるなら外部の死活監視サービス(Uptime Robot の無料枠とか)を1つだけ入れて、ブログのURLを監視させるのが正解です。 自宅サーバの「完全自前」にこだわるなら、nuc3 あたりに最小限の監視スクリプトを置いて、chillarin-ops と chillarin-sv01 の両方をpingする仕組みを入れるのもアリ。
自分はまだ Uptime Robot を入れていないんですが、そのうちやります。たぶん。
Grafana Alerting → Discord 通知の設定
アラートの通知先として Discord を使っています。設定の流れだけ紹介します。
1. Discord Webhook URLを取得
Discord のサーバ設定 → 連携サービス → ウェブフック → 新しいウェブフック → URLをコピー
2. Grafana の Contact Point を設定
Grafana の Alerting → Contact points → Add contact point で、Type に Discord を選び、Webhook URL を入力。
3. Notification Policy を設定
Alerting → Notification policies → Default policy の Contact point を設定したものに変更。
これだけ。Grafana Alerting が Discord Webhook を直接叩くので、通知の仕組みとしてはシンプルに完結します。
なお、compose には Alertmanager コンテナ(:9093)も含めており、Prometheus の向き先としても設定していますが、現時点では receiver: null で無効化しています。将来的に複数チャンネルへのルーティングや抑制ルールが必要になったときの拡張用です。
📦 Discord Webhook の具体的な設定手順(Contact Point の詳細設定・Notification Policy のルーティング設定・テスト通知の確認方法)は 有料コンテンツ: 自宅サーバ構築シリーズ に含まれています。
実際の通知はこんな感じ
Discord に来る通知メッセージはこういう形。
🔥 [FIRING] HostDiskAlmostFull
Instance: chillarin-sv01
ディスク使用率 85% 超 - 現在 87.3%
Source: http://172.16.1.151:3000/alerting/...annotations に日本語で書いておくと、通知も日本語で来るので朝寝ぼけていてもすぐわかります。
ここまでのまとめ(監視基盤編 全体)
3回にわたって監視基盤を紹介しました。振り返るとこんな流れ。
| Part | 内容 | ポイント |
|---|---|---|
| Part1 | 設計思想と全体像 | 4レイヤー監視設計、ツール選定の理由 |
| Part2 | 構築手順 | docker-compose 一発構築、ハマりポイント |
| Part3(本記事) | ダッシュボードと運用知見 | 3枚構成、半年の運用から得た教訓 |
自宅サーバの監視で一番大事なこと は、正直ツールの選定でもダッシュボードの見た目でもなくて、「毎日開く習慣」を作ること だと思っています。 どんなに立派な監視基盤を作っても、見なければ意味がない。
だからこそ、ダッシュボードは3枚に絞って、Overview は10秒で見終わる設計にしています。
これで「Chillarin Blog 構成紹介」シリーズはひと通り完結です。 物理基盤(1章)から始まって、Cloudflare(2章)、Hugo(3章)、Docker(4章)、自動化(5章)、ライブ映像(6章)、ギミック(7章)、そして監視(8章)。 1つのブログの裏側にこれだけのレイヤーが積み重なっている ── というのを伝えられていれば嬉しいです。
今後、会員ポータルや有料コンテンツ基盤の話も書いていく予定ですが、それはまた別シリーズで。
自宅サーバとネットワークの観測の全体像は 自宅 Observability の完全ガイド — Prometheus + Grafana + Loki で家のサーバとネットワークを観測し続ける にまとめています。監視基盤の設計判断から複合障害・retention 運用までを 1 ページで通読できる Pillar ガイドです。
コメント