Vectorの導入と設定:Logstashを代替する超軽量・高パフォーマンスなログパイプライン

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

主要なログパイプラインソリューションの比較

Vectorに移行する前、私のチームは40を超えるマイクロサービスからのログ収集問題に頭を抱えていました。フラッシュセールが開催されるたびに、ログのトラフィックは1時間あたり50GBにまで急増。従来のログシッパーはボトルネックに陥り、サーバークラスターのリソースを食いつぶしていました。

DevOpsエンジニアがよく比較検討する代表的な3つのツールは以下のとおりです。

  • Logstash(Elastic Stack):JVM上で動作。プラグインが豊富でGrokによるパースも手軽ですが、非常に重量級です。空のインスタンスを起動するだけでも1GB〜2GBのメモリを消費します。高負荷時にはガベージコレクションによる一時停止(Stop-the-World)が発生し、キューにデータが滞留してしまいます。
  • Fluent Bit:C言語で記述されており非常に軽量で、メモリ消費量はわずか数十メガバイト程度です。Kubernetesノード上のPodログ収集に最適です。一方で、複雑な文字列のパースやエンリッチ処理には制約が多く、多層にわたる設定ファイルの管理でミスが発生しやすいのが難点です。
  • Vector(Datadogオープンソース):Rust製で完全なメモリ安全性を備えています。実稼働環境でのメモリ消費量はわずか40MB〜80MB程度です。特に付属のVRL(Vector Remap Language)を使用することで、スループットを落とさずに高度なデータ加工が行えます。

メリット・デメリットの徹底比較:Logstash vs Vector

パイプラインを再設計する前に役立つ、実環境での比較表を以下に示します。

項目 Logstash Vector
開発言語 & ランタイム Java (JVM)、JRE/JDKに依存 Rust、単一のネイティブバイナリ、ランタイム依存なし
実稼働時のメモリ消費量 平均スループットで1.5GB〜4GB RAM 同等負荷で40MB〜120MB RAM
データ変換エンジン Grok, Mutate, Rubyスクリプト(処理速度は低速) Vector Remap Language (VRL) – JITコンパイル、型安全
対応データ種別 主にログ(メトリクスの扱いは制限的) Logs、Metrics、Tracesをフルサポート
Sink(出力先)の豊富さ 歴史が長く、ほぼすべてのストレージに対応 Kafka、S3、ClickHouse、ES、Lokiなど主要Sinkを完備

どのような場合にVectorへ切り替えるべきか?

私の環境は15ノードのKubernetesクラスターで運用されています。以前は、サービスで500エラーが大量発生するたびに、ログ収集ノード上のLogstashが即座にOOM Killerの対象となり、CPU使用率は100%に達していました。Grafana上のアラート通知は最大10分も遅延し、障害の根本原因を見失う事態に陥っていました。

以下のような課題に直面している場合は、Vectorへの移行を強くおすすめします。

  • インフラコストを削減したい場合:秒間50,000イベントの負荷下において、Vectorの消費リソースは約1 CPUコアと90MBのRAMで済みます。一方、Logstashでは4コアと3GBのRAMが必要です。
  • エージェントをシンプルに統合したい場合:単一のバイナリでNginxログの読み取り、Dockerコンテナログの収集、クエリ用のClickHouseとコールドストレージ用のS3への並行送信を同時に行えます。
  • 安全にログを検証・パースしたい場合:VRLではnullやパース失敗のハンドリングが必須となっているため、処理途中でプロセス全体がクラッシュするリスクを防げます。

実践ガイド:Nginxログを収集・パースしてElasticsearchへ転送する

ここからは、Nginxのアクセスログを取得し、VRLを用いて未加工の文字列から標準JSONへと整形してElasticsearchへ直接送信する手順を解説します。

ステップ1:Ubuntu/DebianへのVectorのインストール

DatadogはVectorの公式APTリポジトリを提供しています。この方法を利用すれば、最新バージョンへの更新やsystemdによるサービス管理が最もスムーズに行えます。

# Vector公式APTリポジトリを追加
curl -1sLf 'https://repositories.timber.io/public/vector/cfg/setup/bash.deb.sh' | sudo -E bash

# Vectorパッケージをインストール
sudo apt-get update
sudo apt-get install -y vector

# バイナリの動作確認
vector --version

ステップ2:Vectorを構成する3つのコンポーネント

VectorのパイプラインはYAMLまたはTOMLで記述し、主に以下の3つのブロックで構成されます。

  1. Sources(入力元):データ収集元(ログファイル、syslog、journald、ソケット、標準入力など)。
  2. Transforms(変換・加工):データの抽出とクレンジング処理(文字列のパース、型変換、IP情報の付与、不要なログの除外など)。
  3. Sinks(出力先):データの転送先(Elasticsearch、Kafka、ClickHouse、VictoriaLogs、S3など)。

ステップ3:Nginxログ処理パイプラインの作成

/etc/vector/vector.yaml を開き、以下の設定を記述します。

# 1. SOURCES: Nginxのアクセスログファイルを読み取る
sources:
  nginx_access_logs:
    type: "file"
    include:
      - "/var/log/nginx/access.log"
    read_from: "beginning"

# 2. TRANSFORMS: VRLを使用して文字列をパースする
transforms:
  parse_nginx:
    type: "remap"
    inputs:
      - "nginx_access_logs"
    source: |
      # 正規表現でCombined Log Formatを展開
      parsed, err = parse_regex(.message, r'^(?P<remote_addr>[\d\.]+) - (?P<remote_user>[^ ]*) \[(?P<time_local>[^\]]+)\] "(?P<request_method>[A-Z]+) (?P<request_uri>[^ ]+) (?P<server_protocol>[^"]+)" (?P<status>\d+) (?P<body_bytes_sent>\d+)')
      
      if err != null {
        .parse_status = "failed"
      } else {
        ., err = merge(., parsed)
        .status = to_int!(.status)
        .body_bytes_sent = to_int!(.body_bytes_sent)
        .parse_status = "success"
      }
      
      # クエリ用のサーバーラベルを付与
      .host = get_hostname!()
      .service = "nginx-gateway"

# 3. SINKS: Elasticsearchへログを転送し、デバッグ用にコンソール出力する
sinks:
  es_cluster:
    type: "elasticsearch"
    inputs:
      - "parse_nginx"
    endpoints:
      - "http://10.0.0.50:9200"
    mode: "bulk"
    bulk:
      index: "logs-nginx-%Y.%m.%d"
    auth:
      strategy: "basic"
      user: "elastic"
      password: "SecretPassword123"

  stdout_debug:
    type: "console"
    inputs:
      - "parse_nginx"
    encoding:
      codec: "json"

ステップ4:構文チェックとサービスの起動

Vectorには、実行前に設定ファイルの構文エラーを検証する機能が組み込まれています。このコマンドを実行することで、インデントの誤りや変数の指定漏れによるパイプラインの停止リスクを未然に防ぐことができます。

# 設定ファイルを検証
vector validate --config /etc/vector/vector.yaml

# サービスを有効化して起動
sudo systemctl enable --now vector

# 処理ログをリアルタイムで確認
sudo journalctl -u vector -f

設定が有効であれば、Vectorは直ちにアクセスログの読み取りを開始します。remote_addr、status、request_uri などのフィールドがきれいにJSON形式へパースされ、20ミリ秒未満の極めて低いレイテンシでElasticsearchに転送されます。

Share: