LESSON 40分

ストーリー

佐藤CTO
SLI/SLOで『何を測るか』を決めた。次は『どう測るか』— オブザーバビリティ基盤の構築だ
あなた
モニタリングとオブザーバビリティは違うのですか?
佐藤CTO
良い質問だ。モニタリングは既知の問題を検知する。オブザーバビリティは未知の問題を調査できる。マイクロサービスの複雑な世界では、事前にすべての障害パターンを予測することは不可能だ。だからオブザーバビリティが必要なんだ

モニタリング vs オブザーバビリティ

観点モニタリングオブザーバビリティ
目的既知の問題を検知する未知の問題を調査・理解する
アプローチ事前定義のメトリクスとアラートデータの自由な探索と相関分析
質問「システムは正常か?」「なぜシステムは異常なのか?」
データメトリクス中心メトリクス + ログ + トレース
適用場面モノリス、シンプルなシステムマイクロサービス、分散システム

3つの柱(Three Pillars)

graph TD
    Title["オブザーバビリティの3本柱"]

    Title --- Metrics["メトリクス (Metrics)<br/>数値データ<br/><br/>・集約効率◎<br/>・コスト低<br/>・カーディナリティ制限<br/><br/>"何が起きているか""]
    Title --- Logs["ログ (Logs)<br/>イベント記録<br/><br/>・詳細情報◎<br/>・コスト高<br/>・非構造化の場合<br/>検索困難<br/><br/>"詳細は何か""]
    Title --- Traces["トレース (Traces)<br/>リクエストの経路追跡<br/><br/>・因果関係◎<br/>・コスト中<br/>・サンプリングが<br/>必要な場合がある<br/><br/>"どのサービスで起きたか""]

    classDef title fill:#1a1a2e,stroke:#e94560,color:#fff
    classDef pillar fill:#0d6efd,stroke:#0a58ca,color:#fff

    class Title title
    class Metrics,Logs,Traces pillar

各柱の特徴

強み弱み主なツール
メトリクス集約が効率的、長期保存に適する詳細なコンテキストが欠けるPrometheus, Datadog
ログ詳細なイベント情報を含む大量データでコストが高いLoki, Elasticsearch
トレースサービス間の因果関係が見えるサンプリングで一部が欠けるJaeger, Tempo

3本柱の相関

graph TD
    TraceID["Trace ID: abc-123"]
    TraceID --> Metrics["メトリクス<br/>"エラー率が0.5%に上昇""]
    TraceID --> Logs["ログ<br/>"Payment API:<br/>connection timeout<br/>to DB at 14:23:05""]
    TraceID --> Traces["トレース<br/>"API Gateway →<br/>Payment Service (timeout 3.2s)<br/>→ DB (no response)""]
    Metrics --- Correlate["Trace IDで3つを横断的に追跡"]
    Logs --- Correlate
    Traces --- Correlate

    classDef traceId fill:#e94560,stroke:#c23050,color:#fff
    classDef metrics fill:#0d6efd,stroke:#0a58ca,color:#fff
    classDef logs fill:#198754,stroke:#146c43,color:#fff
    classDef traces fill:#f5a623,stroke:#c47d10,color:#fff
    classDef correlate fill:#6c757d,stroke:#495057,color:#fff

    class TraceID traceId
    class Metrics metrics
    class Logs logs
    class Traces traces
    class Correlate correlate

OpenTelemetry入門

OpenTelemetryとは

OpenTelemetry(OTel)は、テレメトリデータ(メトリクス、ログ、トレース)の生成・収集・エクスポートのためのオープンソース標準です。

# OpenTelemetryの構成要素
components:
  api:
    description: "計装(Instrumentation)のためのインターフェース"
    role: "アプリケーションコードにテレメトリの計装ポイントを定義"

  sdk:
    description: "APIの実装"
    role: "テレメトリデータの処理、サンプリング、エクスポート"

  collector:
    description: "テレメトリデータの収集・加工・転送"
    role: "ベンダー非依存のデータパイプライン"

  exporters:
    description: "バックエンドへのデータ送信"
    destinations:
      - Prometheus (メトリクス)
      - Jaeger / Tempo (トレース)
      - Loki / Elasticsearch (ログ)

OpenTelemetry Collectorのアーキテクチャ

graph LR
    NodeApp["App (Node.js)"] --> Collector
    PythonApp["App (Python)"] --> Collector
    GoApp["App (Go)"] --> Collector

    subgraph Collector["OpenTelemetry Collector"]
        Receivers["Receivers"] --> Processors["Processors"] --> Exporters["Exporters"]
    end

    Collector --> Prometheus["Prometheus<br/>(メトリクス)"]
    Collector --> Jaeger["Jaeger<br/>(トレース)"]
    Collector --> Loki["Loki<br/>(ログ)"]

    classDef app fill:#6c757d,stroke:#495057,color:#fff
    classDef collector fill:#0d6efd,stroke:#0a58ca,color:#fff
    classDef backend fill:#198754,stroke:#146c43,color:#fff

    class NodeApp,PythonApp,GoApp app
    class Receivers,Processors,Exporters collector
    class Prometheus,Jaeger,Loki backend

Node.jsでのOpenTelemetry設定

import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { Resource } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';

const sdk = new NodeSDK({
  resource: new Resource({
    [ATTR_SERVICE_NAME]: 'payment-service',
    [ATTR_SERVICE_VERSION]: '1.2.0',
    'deployment.environment': process.env.NODE_ENV ?? 'development',
  }),

  // トレースエクスポーター
  traceExporter: new OTLPTraceExporter({
    url: 'http://otel-collector:4318/v1/traces',
  }),

  // メトリクスエクスポーター
  metricReader: new PeriodicExportingMetricReader({
    exporter: new OTLPMetricExporter({
      url: 'http://otel-collector:4318/v1/metrics',
    }),
    exportIntervalMillis: 15000,
  }),

  // 自動計装(HTTP, Express, pg, redis等)
  instrumentations: [
    getNodeAutoInstrumentations({
      '@opentelemetry/instrumentation-http': {
        ignoreIncomingRequestHook: (req) => {
          return req.url === '/health' || req.url === '/ready';
        },
      },
    }),
  ],
});

sdk.start();
console.log('OpenTelemetry SDK started');

// グレースフルシャットダウン
process.on('SIGTERM', async () => {
  await sdk.shutdown();
  console.log('OpenTelemetry SDK shut down');
  process.exit(0);
});

OpenTelemetry Collector設定

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 5s
    send_batch_size: 1000

  # リソース属性の追加
  resource:
    attributes:
      - key: environment
        value: production
        action: upsert

  # メモリ制限
  memory_limiter:
    check_interval: 5s
    limit_mib: 512
    spike_limit_mib: 128

exporters:
  # Prometheusへのメトリクス送信
  prometheus:
    endpoint: 0.0.0.0:8889
    namespace: otel

  # Jaeger/Tempoへのトレース送信
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true

  # Lokiへのログ送信
  loki:
    endpoint: http://loki:3100/loki/api/v1/push

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch, resource]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [prometheus]
    logs:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [loki]
OpenTelemetry vs ベンダー固有ソリューション
観点OpenTelemetryベンダー固有(Datadog等)
ロックインなし(オープン標準)バックエンド変更が困難
自動計装対応(主要フレームワーク)対応(より豊富な場合も)
運用負荷Collectorの管理が必要SaaS型で運用不要
コストOSS(インフラコストのみ)ライセンス費用
カスタマイズ高い自由度プロバイダの機能に制限
コミュニティCNCF、活発な開発ベンダーサポート

多くの組織では、OpenTelemetryでデータを収集し、バックエンドはDatadog/New Relic等のSaaSを使う「ハイブリッドアプローチ」が採用されています。


まとめ

ポイント内容
モニタリング vs オブザーバビリティ既知の問題検知 vs 未知の問題調査
3本柱メトリクス(数値)、ログ(イベント)、トレース(経路)
相関分析Trace IDで3つの柱を横断的に追跡
OpenTelemetryテレメトリの収集・加工・送信のオープン標準
Collectorベンダー非依存のデータパイプライン

チェックリスト

  • モニタリングとオブザーバビリティの違いを説明できる
  • 3本柱(メトリクス・ログ・トレース)の特徴と使い分けを理解した
  • 3本柱のデータ相関の仕組み(Trace ID)を理解した
  • OpenTelemetryの構成要素とアーキテクチャを把握した
  • Node.jsでのOpenTelemetry設定を実装できる

次のステップへ

次は「Prometheus/Grafana」を深掘りします。Prometheusのアーキテクチャ、PromQLの応用、Grafanaのベストプラクティスを学びましょう。


推定読了時間: 40分