目次

読了時間: 約 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, ERROR
  • service: サービス名
  • 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 }} がダウンしています"

アラート疲労の防止

問題: 多すぎるアラート→アラート無視→障害見逃し

対策:

  1. アラート数を絞る: アクション可能なアラートのみ
  2. 適切な閾値: フラップ防止のため hysteresis を設定
  3. 集約: 関連アラートをグループ化
  4. 自動回復: 自己修復と連動

So What?——実務への応用

  • メトリクスから始める: まずは RED/USE メトリクスを収集
  • 構造化ログを徹底: 一貫性のあるログフォーマット
  • トレース ID を全レイヤーで: ログ・メトリクス・トレースの相関
  • アラートは少なく鋭く: アクション可能なもののみ
  • ダッシュボードは生きたドキュメント: 定期的に見直し
  • OpenTelemetry で標準化: ベンダーロックイン回避

監視とオブザーバビリティは、現代システム運用の「目」と「脳」だ。投資効果は明確——MTTR(平均修復時間)の短縮、顧客体験の向上、開発者生産性の向上。

参考リンク

免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。