目次
読了時間: 約 14 分 | 文字数: 約 5,200 字
「監視は_fire alarm_、オブザーバビリティは_fire investigation_」——この比喩が両者の違いを的確に表している。監視は「何かがおかしい」ことを知らせ、オブザーバビリティは「なぜおかしいのか」を解明する。クラウドネイティブな現代システムにおいて、両者は不可欠なインフラだ。本稿では、監視とオブザーバビリティの基礎と、主要ツールを使った実践を解説する。
監視 vs オブザーバビリティ
従来の監視(Monitoring)
「既知の未知」を扱う——何が問題になるか予測可能。
監視の質問:
- 「サーバーは稼働しているか?」
- 「CPU 使用率の閾値を超えていないか?」
- 「エラーレートは増加していないか?」
アプローチ:
1. 監視すべき指標を事前に定義
2. 閾値を設定
3. 閾値超過時にアラート
用途: 障害検知、SLA 監視、キャパシティプランニング
オブザーバビリティ(Observability)
「未知の未知」を扱う——何が問題になるか予測不可能。
オブザーバビリティの質問:
- 「なぜユーザー A のリクエストだけ遅いのか?」
- 「このバグはどのサービス変更が原因か?」
- 「新規デプロイ後のシステム挙動は?」
アプローチ:
1. 高基数のテレメトリデータを収集
2. 任意の次元で集計・分析
3. 仮説検証を繰り返す
用途: 本番環境のデバッグ、パフォーマンス調査、新機能の影響分析
3 つの柱(Three Pillars)
オブザーバビリティは 3 つのデータソースで構成される。
| 柱 | 説明 | 代表ツール |
|---|---|---|
| メトリクス | 時系列数値データ(CPU、メモリ、リクエスト数) | Prometheus, Datadog |
| ログ | イベント記録(アプリケーションログ、アクセスログ) | Elasticsearch, Loki |
| トレース | リクエストの流れ(分散トレーシング) | Jaeger, Zipkin |
ユーザーリクエストの流れ:
1. メトリクス:「API レイテンシが 500ms→1200ms に増加」
↓ 何かが起きている
2. ログ:「ERROR: Database connection timeout」
↓ データベースに問題
3. トレース:「/api/users → /api/orders → DBクエリ」の遅延箇所を特定
↓ どのクエリが遅いか特定
メトリクス監視——Prometheus
Prometheus の基本
Prometheus: オープンソースの監視・アラートツールキット。
アーキテクチャ:
┌─────────────┐ ┌─────────────┐
│ ターゲット │ ──→ │ Prometheus │
│ (exporter) │ pull│ Server │
└─────────────┘ └──────┬──────┘
│
┌──────▼──────┐
│ TSDB │
│ (時系列DB) │
└──────┬──────┘
│
┌──────▼──────┐
│ PromQL │
│ (クエリ言語) │
└─────────────┘
特徴:
- Pull モデル: Prometheus がターゲットから能動的に収集
- 多次元データ: メトリクス名+ラベルで識別
- PromQL: 強力なクエリ言語
メトリクスの形式
# 基本形式
metric_name{label1="value1", label2="value2"} value timestamp
# 例
http_requests_total{method="POST", handler="/api/users", status="200"} 1024
http_requests_total{method="POST", handler="/api/users", status="500"} 3
メトリクスの 4 タイプ
| タイプ | 説明 | 例 |
|---|---|---|
| Counter | 増加のみ(リセットあり) | リクエスト数、エラー数 |
| Gauge | 増減する値 | CPU 使用率、メモリ使用量 |
| Histogram | 値の分布 | レイテンシ、リクエストサイズ |
| Summary | パーセンタイル計算 | レイテンシの p95, p99 |
Prometheus 設定例
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- 'alerts.yml'
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'application'
static_configs:
- targets: ['app:8080']
metrics_path: '/metrics'
主要 PromQL クエリ
# 直近 5 分間の平均 CPU 使用率
avg(rate(node_cpu_seconds_total[5m]))
# エラーレートの計算
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
# リクエストレイテンシの p99
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
# 前週比の計算
sum(rate(http_requests_total[1h]))
/
sum(rate(http_requests_total[1h] offset 1w))
可視化——Grafana
Grafana の基本
Grafana: メトリクス・ログ・トレースの可視化プラットフォーム。
データフロー:
Prometheus/Elasticsearch/等 → Grafana → ダッシュボード
↓
アラート
特徴:
- マルチデータソース: 複数の DB を横断的に可視化
- テンプレート変数: 動的なダッシュボード
- アラート機能: 閾値超過時に通知
- アノテーション: デプロイイベントなどを表示
ダッシュボード設計のベストプラクティス
1. 階層構造を作る:
レベル 1: 経営/マネージャー向け
- SLA 達成率
- エラーバジェット消費
- ビジネスメトリクス
レベル 2: 開発者向け
- サービス別レイテンシ
- エラーレート
- スループット
レベル 3: 運用/SRE 向け
- インフラメトリクス(CPU、メモリ、ディスク)
- ネットワーク I/O
- 詳細なエラーログ
2. RED メソッド(Request, Error, Duration):
各サービスに 3 つのグラフ:
1. Request Rate: 秒間リクエスト数
2. Error Rate: エラーレスポンスの割合
3. Duration: レイテンシ(p50, p95, p99)
3. USE メソッド(Utilization, Saturation, Errors):
各リソースに 3 つのグラフ:
1. Utilization: リソース使用率
2. Saturation: キュー長、処理待ち
3. Errors: ハードウェアエラー
分散トレーシング——OpenTelemetry + Jaeger
OpenTelemetry の基本
OpenTelemetry: クラウドネイティブコンピューティング財団(CNCF)のトレーシング標準。
アーキテクチャ:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ アプリケーション │ ──→ │ OTel │ ──→ │ バックエンド │
│ (instrument) │ │ Collector │ │ (Jaeger 等) │
└─────────────┘ └─────────────┘ └─────────────┘
特徴:
- ベンダーニュートラル: 特定ベンダーにロックインされない
- 自動 Instrumentation: 主要言語・フレームワーク対応
- Correlation: トレース ID でログ・メトリクスと紐付け
トレースの構成要素
Trace(trace_id: abc123)
├── Span 1(span_id: 001)
│ ├── 名前:GET /api/users
│ ├── 開始時間:10:00:00.000
│ ├── 終了時間:10:00:00.150
│ ├── 属性:method=GET, status=200
│ └── イベント:db_query_start, db_query_end
│
├── Span 2(span_id: 002, parent: 001)
│ └── 名前:SELECT * FROM users
│
└── Span 3(span_id: 003, parent: 001)
└── 名前:cache_lookup
OpenTelemetry 実装例(Node.js)
// インストール
// npm install @opentelemetry/sdk-node @opentelemetry/instrumentation-http
const { NodeSDK } = require('@opentelemetry/sdk-node')
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http')
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger')
const sdk = new NodeSDK({
serviceName: 'user-service',
instrumentations: [new HttpInstrumentation()],
traceExporter: new JaegerExporter({
endpoint: 'http://jaeger:14268/api/traces',
}),
})
sdk.start()
自動 Instrumentation
# Java(自動)
java -javaagent:/path/to/opentelemetry-javaagent.jar \
-Dotel.service.name=my-app \
-jar my-app.jar
# Python
opentelemetry-instrument python app.py
# Go
# ビルド時に埋め込み
go build -ldflags="-X 'go.opentelemetry.io/contrib/instrumentation/runtime'"
ログ管理——ELK Stack vs Loki
ELK Stack(Elasticsearch, Logstash, Kibana)
フル機能ログ管理プラットフォーム。
アーキテクチャ:
アプリケーション → Filebeat → Logstash → Elasticsearch → Kibana
| 特徴 | 詳細 |
|---|---|
| 全文検索 | 強力、柔軟 |
| スケーラビリティ | 大規模対応 |
| リソース | 比較的多い |
| ユースケース | 複雑なログ分析、セキュリティ |
Loki
軽量ログ集約システム(Grafana Labs 製)。
アーキテクチャ:
アプリケーション → Promtail → Loki → Grafana
| 特徴 | 詳細 |
|---|---|
| インデックス | ラベルのみ(軽量) |
| コスト | 低コスト |
| 統合 | Grafana とシームレス |
| ユースケース | Kubernetes、クラウドネイティブ |
ログ設計のベストプラクティス
構造化ログ(JSON):
{
"timestamp": "2025-08-10T12:34:56.789Z",
"level": "ERROR",
"service": "user-service",
"trace_id": "abc123",
"span_id": "001",
"message": "Database connection failed",
"error": {
"type": "ConnectionTimeoutError",
"stack": "..."
},
"context": {
"user_id": "user_456",
"request_id": "req_789"
}
}
必須フィールド:
timestamp: ISO 8601 形式level: DEBUG, INFO, WARN, ERRORservice: サービス名trace_id: トレーシングとの相関用
アラート設計
アラートの階層化
レベル 1: ページ(即時対応)
- サービスダウン
- エラーレート 5% 超
- レイテンシ p99 > 5 秒
レベル 2: チケット(営業時間内対応)
- エラーレート 1-5%
- ディスク使用率 80% 超
- メモリリーク疑い
レベル 3: 情報(定例レビュー)
- トレンド変化
- キャパシティ予測
アラートルールの例
# alerts.yml
groups:
- name: service-alerts
rules:
- alert: HighErrorRate
expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.01
for: 5m
labels:
severity: critical
annotations:
summary: "エラーレート 1% 超"
description: "{{ $labels.service }} のエラーレートが {{ $value | humanizePercentage }} に達しています"
- alert: HighLatency
expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 5
for: 10m
labels:
severity: warning
annotations:
summary: "レイテンシ p99 が 5 秒超"
description: "{{ $labels.service }} のレイテンシ p99 が {{ $value }}s です"
- alert: ServiceDown
expr: up{job="application"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "サービスダウン"
description: "{{ $labels.instance }} がダウンしています"
アラート疲労の防止
問題: 多すぎるアラート→アラート無視→障害見逃し
対策:
- アラート数を絞る: アクション可能なアラートのみ
- 適切な閾値: フラップ防止のため hysteresis を設定
- 集約: 関連アラートをグループ化
- 自動回復: 自己修復と連動
So What?——実務への応用
- メトリクスから始める: まずは RED/USE メトリクスを収集
- 構造化ログを徹底: 一貫性のあるログフォーマット
- トレース ID を全レイヤーで: ログ・メトリクス・トレースの相関
- アラートは少なく鋭く: アクション可能なもののみ
- ダッシュボードは生きたドキュメント: 定期的に見直し
- OpenTelemetry で標準化: ベンダーロックイン回避
監視とオブザーバビリティは、現代システム運用の「目」と「脳」だ。投資効果は明確——MTTR(平均修復時間)の短縮、顧客体験の向上、開発者生産性の向上。
参考リンク
- Prometheus 公式ドキュメント — メトリクス収集の標準
- Grafana Labs ドキュメント — 可視化プラットフォーム
- OpenTelemetry 公式 — 分散トレーシング標準
- Google SRE ブック — 監視の設計思想
免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。