なぜWindows Server用に個別でセットアップする必要があるのか?
このブログのPrometheus + Grafanaインストール記事を読んだことがある方は、ほとんどの説明がnode_exporterを使ったLinux向けであることに気づいているはずです。Windows Serverは別の話です — ファイルシステムも違えば、サービス管理の仕組みも異なる。そして何よりWindows Servicesは独立して監視する必要があります。
以前、IISを動かしているWindowsサーバーで夜中の3時にサービスがフリーズしたことがあります。お客様から電話がくるまで誰も気づかなかった。その経験があってから、本腰を入れてWindows用の監視をセットアップしました。この記事はまさにその問題に集中します:CPU、RAM、ディスク、そしてServicesの状態 — 余計な話は省きます。
Windowsを監視するためのオプションは何があるか?
何かインストールする前に、どんな選択肢があるか把握しておきましょう:
1. Windows Exporter(Prometheus向け)
旧wmi_exporterからフォークされ、現在はPrometheusコミュニティの公式プロジェクトです。HTTPエンドポイント経由でメトリクスをエクスポートし、Prometheusが定期的にスクレイプします。バックグラウンドのWindows Serviceとして動作し、フットプリントが小さく — わずか15〜20MB程度のRAMしか使いません。
2. Telegraf + InfluxDB
InfluxDataの汎用エージェントで、ネイティブのWindows Performance Countersを使用するwin_perf_countersプラグインを備えています。Windows対応は優れていますが、より重く(~50MB RAM)、設定が多く、InfluxDBの追加かoutputプラグイン経由でPrometheusへの転送が必要です。
3. Zabbix Agent
Zabbixには独自のWindows用エージェントがあり、充実したテンプレートが揃っています。しかしPrometheusをメインバックエンドとして使っている場合、Zabbixを追加するのは不必要な複雑さを招きます — 二つのエコシステムを並行して、二箇所でメンテナンスが必要になる。
4. SNMP / WMI 直接利用
エージェントをインストールせずにPrometheusからメトリクスをプルします。シンプルに聞こえますが、レイテンシが高く、設定が複雑で、アプリケーションレベルの監視には詳細が不足しています。通常はエージェントをインストールできないネットワーク機器に対してのみ使用します。
簡易比較
| アプローチ | メリット | デメリット |
|---|---|---|
| Windows Exporter | Prometheusネイティブ、軽量(~15MB RAM)、豊富なメトリクス | Prometheusが必要 |
| Telegraf | 汎用性が高く、多くのoutputプラグインあり | より重め(~50MB)、設定が多い |
| Zabbix Agent | 豊富なテンプレート、洗練されたUI | 独自エコシステムでPrometheusとは共用不可 |
| SNMP/WMI | エージェント不要 | レイテンシが高く、アプリレベルの詳細が不足 |
どれを選ぶべきか?
LinuxサーバーにPrometheus + Grafanaを使っているなら?答えはほぼ常にWindows Exporterです。同じスクレイプ設定、同じAlertmanager、同じGrafana — 新しいターゲットを一つ追加するだけ。新しいスタックを学ぶ必要はありません。
唯一の例外:すでにZabbixを使っていてWindows Serverが少数の場合 → 統一性のためにZabbix Agentを使う。それ以外は、この記事はWindows Exporterに直進します。
デプロイメントガイド
ステップ1:Windows ServerにWindows Exporterをインストールする
prometheus-community/windows_exporterのGitHubリリースから最新のMSIをダウンロードします。執筆時点ではv0.29.2です。
Administratorの権限でPowerShellからインストールします:
# MSIをダウンロード
$version = "0.29.2"
$url = "https://github.com/prometheus-community/windows_exporter/releases/download/v$version/windows_exporter-$version-amd64.msi"
Invoke-WebRequest -Uri $url -OutFile "windows_exporter.msi"
# 必要なコレクターと共にインストール
msiexec /i windows_exporter.msi `
ENABLED_COLLECTORS="cpu,memory,logical_disk,net,os,service,system" `
LISTEN_PORT="9182" /quiet
GUIから手動でインストールすることもできます。ポート9182(デフォルト)を選択してください。インストール後、windows_exporterという名前のWindows Serviceが自動的に起動します。
サービスが実行中であることを確認します:
Get-Service windows_exporter
# ステータスはRunningであること
そのサーバーから直接メトリクスエンドポイントをテストします:
Invoke-WebRequest -Uri http://localhost:9182/metrics | Select-Object -ExpandProperty Content | Select-String "windows_cpu"
ステップ2:PrometheusスクレイプのためにFirewallを開放する
New-NetFirewallRule `
-DisplayName "Windows Exporter" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 9182 `
-Action Allow
全体を開放するのではなく、PrometheusサーバーのIPだけにルールを制限するのが望ましい — -RemoteAddress 192.168.1.50を一行追加するだけで十分です。
ステップ3:PrometheusにターゲットをAddする
Prometheusサーバー(Linux)でprometheus.ymlを編集します:
scrape_configs:
# ... 既存のLinuxジョブ ...
- job_name: 'windows_servers'
static_configs:
- targets:
- '192.168.1.100:9182' # Windowsサーバー1
- '192.168.1.101:9182' # Windowsサーバー2
labels:
env: 'production'
os: 'windows'
Prometheusをリロードして適用します:
curl -X POST http://localhost:9090/-/reload
# または
systemctl reload prometheus
Prometheus UI → Status → Targetsに移動すると、windows_serversターゲットのstateがUPになっているはずです。DOWNになっている場合は、まずFirewallを確認してください — 10件中9件はそれが原因です。
ステップ4:GrafanaダッシュボードをImportする
ダッシュボードID 14694(Windows Exporter Node)はコミュニティで最も人気のある選択肢です。Grafanaにインポートします:
- Grafana → Dashboards → Import
- ID
14694を入力 → Load - Prometheusデータソースを選択 → Import
ダッシュボードにはCPU使用率、RAM、ディスクI/O、ネットワークスループットのパネルが揃っています。instance変数を調整して、確認したいサーバーを選択してください。複数のサーバーがある場合、この変数はドロップダウン形式で表示されます — 非常に便利です。
ステップ5:特定のWindows Servicesを監視する
これがLinux監視との最大の違いです。使用するメトリクスはwindows_service_stateです:
# サービスが実行中かどうかを確認(1 = running)
windows_service_state{state="running", name="W3SVC"} # IIS
windows_service_state{state="running", name="MSSQLSERVER"} # SQL Server
windows_service_state{state="running", name="wuauserv"} # Windows Update
# サービスが突然停止した際にアラート — シンプルで効果的な方法
windows_service_state{name=~"W3SVC|MSSQLSERVER|SQLSERVERAGENT", state="running"} == 0
上記のクエリを使ったパネルをGrafanaに追加し、Stat形式またはTable形式のビジュアライゼーションで各サービスの状態を視覚的に確認できます。
実践的なアラートルール
この部分が最初に最も時間がかかった箇所です。アラート疲れ(Alert fatigue)は抽象的な概念ではありません — 実際に経験しました:セットアップ完了後、実際のワークロードに合わないthresholdのせいで夜中の2時に頻繁にアラートが飛んでくる。無効にして無視し、システム全体への信頼を失う。何度もチューニングを繰り返してようやく安定しました。
現在使用しているwindows_alerts.ymlファイルです。Grafanaのメールアラート設定と組み合わせることで、アラート通知チャネルを一元管理できます:
groups:
- name: windows_server
rules:
# 10分間継続してCPUが高い場合 — 短時間のスパイクは正常なのでアラートしない
- alert: WindowsCPUHigh
expr: |
100 - (avg by (instance) (
rate(windows_cpu_time_total{mode="idle"}[5m])
) * 100) > 85
for: 10m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }}でCPUが高い"
description: "CPU使用率 {{ $value | printf \"%.1f\" }}%が10分間継続"
# 残りRAMが500MB未満(絶対値、%ではない)
- alert: WindowsLowMemory
expr: windows_os_physical_memory_free_bytes < 500 * 1024 * 1024
for: 5m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }}でRAMが低い"
description: "空きRAMが{{ $value | humanize1024 }}Bのみ"
# ディスクが10%未満
- alert: WindowsDiskLow
expr: |
(windows_logical_disk_free_bytes{volume!~"HarddiskVolume.*"}
/ windows_logical_disk_size_bytes) * 100 < 10
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }}の{{ $labels.volume }}ディスク容量が少ない"
# 重要なサービスが停止した場合
- alert: WindowsServiceDown
expr: |
windows_service_state{
name=~"W3SVC|MSSQLSERVER|SQLSERVERAGENT",
state="running"
} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }}でサービス{{ $labels.name }}が停止"
ルールをPrometheusに読み込むにはprometheus.ymlに以下を追加します:
rule_files:
- "/etc/prometheus/rules/windows_alerts.yml"
深夜のアラートで叩き起こされた後の教訓
理論ではなく、痛い経験から得た教訓です:
for: 10mを使い、即座にトリガーしない — バックアップ実行やWindows Updateの際の1分程度のCPUスパイクは正常です。10分間継続してCPUが高い場合のみ問題です。- severityはwarningから始め、criticalにしない — criticalは本当に夜中の3時に起き上がって修正が必要な時だけ使います。
- Alertmanagerを有効にする前に1〜2週間監視する — サーバーの実際のパターンを確認し、感覚ではなく実際の数値に基づいてthresholdを設定します。
- 特定のサービス名でアラートを設定する、停止した全サービスにアラートを出さない — Windowsには常時起動が不要なサービスが数十個あり、全部アラートするとすぐに混乱します。
パイプライン全体のテスト
# Prometheusサーバーから手動で接続テスト
curl http://192.168.1.100:9182/metrics | grep -E "windows_(cpu|memory|service)"
# このクエリはPrometheus UIで結果を返すはずです:
# windows_os_physical_memory_free_bytes{instance="192.168.1.100:9182"}
PrometheusにメトリクスがあらわれてGrafanaダッシュボードにデータが読み込まれれば、パイプラインは正常に動作しています。あとはサーバーごとにアラートのthresholdを調整するだけです。
