🌹

ログ収集ソフトウェアVectorの導入

に公開

はじめに

こんにちは。スマサテ株式会社でアプリケーションエンジニアをしているサカモトです。
先日、ログ収集ソフトウェアのVectorを導入し、アプリケーションのログを収集するパイプラインの構築が完了しました。
この記事では、Vectorの導入背景や構成について紹介します。

背景

スマサテではバックエンドのWebフレームワークとしてRuby on Railsを使用しています。
gemのLogrageを使用して構造化されたRailsログを出力し、何かトラブルなどでログを追跡したいケースが発生した際には
直接ホストへSSHでログインしてログファイルを参照したり、CloudWatchのロググループを確認したりしていました。

しかしWebサーバーは複数のホストに分散しており、またRailsのログだけではなくnginxのログや、アプリの機能で出力されるログもあるため、
ホストやファイルをまたがってログを確認するのは非常に手間がかかります。
またそれでは検索や集計にも限界があり、ログの可視化や分析を行うのは難しい状況でした。
何より調査時に、Slackに生のログファイルをペタペタ貼り付けるのは、基本的に視認性が悪くコミュニケーションの効率も低下してしまいます。

そこで、ログ収集ソフトウェアを導入して、ログの一元管理と可視化を行える基盤を整えることにしました。

Vectorの選定

ログ収集ソフトウェアには様々な選択肢がありますが、タイトルの通り Vector を選定しました。
Vectorは、ログの収集・変換・転送を行うためのRust製オープンソースソフトウェアであり、 非常に高速で効率的なログ処理が可能な点が大きな特徴 です。

Vector enables dramatic cost reduction, novel data enrichment, and data security where you need it, not where is most convenient for your vendors. Open source and up to 10x faster than every alternative.

- Vector公式サイト より引用

一方で、Fluentdなどと比較すると、まだコミュニティの規模が小さく、情報が少ない(Vector自体の検索性も低い)という点もあります。
メンバーにヒアリングを行い、他のログ収集ソフトウェアではそれによってCPU使用率が高くなったというような話もあったため、Vectorのパフォーマンスの高さに期待を寄せて導入を決定しました。

構成

基盤の構成は以下のようにしました。

production-1とproduction-2は、それぞれRailsアプリケーションが稼働しているホストを表しています(ここでは2つのホストを例にしております)。

この構成は、Vectorのドキュメントにある「Centralized Topology」を参考にしています。
https://vector.dev/docs/setup/deployment/topologies/#centralized

各ホストにVectorを Agent として導入し、Railsアプリケーションやnginxのログを収集し、それらをVectorがaggregatorサーバーに転送します。
aggregatorサーバーでは、稼働しているVectorが Aggregator として 受け取ったログを集約、整形し、Elasticsearchに転送します。

他にも「Distributed Topology」や「Stream based Topology」などの構成もありますが、
Distributed Topologyでは、各アプリケーションサーバーでの変換やバッファリングででコストがかかること、
Stream based Topologyを採用するほど大規模ではなく、Kafkaなどのストリームサービスを導入するコストがかかってしまうことから、
Centralized Topologyを選定しました。

安定性について

ログは完全性が求められるため、ログの欠損などを最小限に抑えるような設定や構成を目指す必要があります。
Vectorは、ログの収集・転送において高い安定性を提供するための機能を備えています。

リトライとバッファリング

Vectorは、ログの転送においてリトライやバッファリングの機能を提供しており、これによりsink先の一時的な障害やネットワークの問題が発生してもログの欠損を防ぐことができます。

Vectorは送信先への接続失敗やタイムアウトが発生した場合、自動的にリトライを行います。デフォルトでは無制限にリトライを試みます。

sinks.vector.retry-policy
sinks.elasticsearch.retry-policy

リトライの回数や間隔は設定可能で、必要に応じて調整できます。
また、Vectorはログを一時的にバッファリングする機能も提供しており、これにより一時的な障害が発生してもログを失うことなく、後で再送信することができます。
バッファをディスクに保存する設定を行うことで、メモリ不足によるログの欠損を防ぐことができます。また、満杯時はログの転送を一時停止し、 バッファが空になるまで待機する設定を行うことも可能です。

# Vectorの設定例
# sink先がElasticsearchの場合も同様の設定が可能
# request.retry_attemptsはデフォルトで実質無制限にリトライを行う設定なので未指定
sinks:
  to_aggregator:
    type: vector
    inputs: [source]
    endpoint: "http://aggregator:9000"
    buffer:
      type: disk
      max_size: 1000000 # バッファの最大サイズを設定
      when_full: block # バッファが満杯になった場合、ログの転送を一時停止し、バッファが空になるまで待機(デフォルトで block)

これらの機能により、aggregatorが一時的にダウンしたり、Elasticsearchへの接続が不安定になった場合でも、各ホストのVectorエージェントはログをバッファリングし、接続が回復次第自動的に転送を再開します。
さらに加えて、aggregatorサーバーは、内製の死活監視ツールでも監視を行い、Vectorの停止時にはsystemdによる再起動を行うことで、より安全に運用できるようにしています。

取り組みについて

スマサテではこうした技術的課題を解決する取り組みをワーキンググループとして行っています。
今回のような対応は、もしかしたら本来はインフラやSREの担当が行うことかもしれませんが、
僕のようなアプリケーションエンジニアでも、レイヤーにとらわれず課題を解決するために積極的に取り組むことのできる環境があります。

そうした取り組みに興味のある方、あるいはプロダクトや事業に関心のある方は、ぜひスマサテの採用情報もご覧ください。

https://www.wantedly.com/projects/2099580

参考

スマサテ Tech Blog

Discussion