TECH · OBSERVABILITY · HOMESERVER

Chillarin Blog 構成紹介 - 8.監視基盤編 Part3(ダッシュボード設計と運用知見)-

Grafanaダッシュボードの設計方針と、自宅サーバを半年以上運用して得た監視の知見。「見るべきもの」と「見なくていいもの」の線引き。

tech 2026-03-31 57 min read by ちらりん
cover · 1024×1024

はじめに

Part1(設計思想と全体像)で「何を監視するか」、Part2(構築手順編)で「どう構築するか」を紹介しました。

最終回の Part3 では、Grafana ダッシュボードの設計 と、実際に半年以上運用してみてわかった 「見るべきメトリクス」「見なくていいメトリクス」 の話をします。

正直、監視は「入れた直後」が一番モチベーション高くて、気づいたらダッシュボードを開かなくなる……というのが自宅サーバあるある。 どうすれば「開き続けるダッシュボード」になるのか、自分なりの答えを書いてみます。


ダッシュボード設計の方針

最初に結論を言うと、ダッシュボードは 3枚 に絞っています。

#名前目的見る頻度
1Overview全ホスト・全コンテナの健康状態を一目で毎日(朝のルーティン)
2Blog Analyticsブログのアクセス状況 + Cloudflare 統計週1〜2回
3Troubleshootトラブル発生時のメトリクス + ログ横断問題が起きた時だけ

最初は「ホスト用」「コンテナ用」「nginx用」「ログ用」…… と分けて7〜8枚作ったんですが、結局見なくなりました。 ダッシュボードが増えるほど「どこを見ればいいかわからない」という本末転倒な状態になります。

今は 「毎日見る1枚」+「たまに見る1枚」+「消火活動用1枚」 の3枚構成に落ち着いています。


Dashboard 1: Overview(毎日見るやつ)

このダッシュボードの設計思想は 「10秒で全体の健康状態がわかる」 です。

構成

上から順に、こういうレイアウトにしています。

snippet
┌────────────────────────────────────────────────────────────┐
│  [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回見るやつ)

このダッシュボードはブログの運営指標を見るためのものです。

構成

snippet
┌─────────────────────────────────────────────────────────┐
│  [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 → Prometheus5分
記事別PVCloudflare Analytics API → Prometheus5分
リクエスト数 / ステータスコードnginx-exporter → Prometheus15秒

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(テンプレート変数) を多用しています。

snippet
変数: $host    = chillarin-sv01 | nuc1 | nuc2 | nuc3
変数: $container = nginx | hugo-blog | remark42 | cloudflared | ...
変数: $timerange = (Grafana デフォルトの時間範囲ピッカー)

上部のドロップダウンでホストやコンテナを切り替えると、全パネルが連動して絞り込まれます。

レイアウト

snippet
┌─────────────────────────────────────────────────────────┐
│  [$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 を確認して「あ、別にいいやつだ」で閉じる ── という無駄が発生していました。 これが続くと通知を無視するようになって、本当に大事なアラートも見逃すようになります。

最終的に残したアラート(再掲):

  1. HostDiskAlmostFull(85%超)
  2. ContainerDown(主要コンテナが5分以上停止)
  3. HighMemoryUsage(90%超が10分以上)
  4. 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日大量に出るので短め
syslog30日カーネルパニックやOOMの記録は残す

Loki 側の retention_period はグローバル設定なので、ログの種類別に保持期間を変えたい場合は limits_configper_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 に来る通知メッセージはこういう形。

snippet
🔥 [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つのブログの裏側にこれだけのレイヤーが積み重なっている ── というのを伝えられていれば嬉しいです。

今後、会員ポータルや有料コンテンツ基盤の話も書いていく予定ですが、それはまた別シリーズで。

← Part2: 構築手順編

← シリーズ一覧に戻る


自宅サーバとネットワークの観測の全体像は 自宅 Observability の完全ガイド — Prometheus + Grafana + Loki で家のサーバとネットワークを観測し続ける にまとめています。監視基盤の設計判断から複合障害・retention 運用までを 1 ページで通読できる Pillar ガイドです。

· · ·

コメント