WEB+DB PRESS plusシリーズFluentd実践入門
──統合ログ基盤のためのデータ収集ツール

書籍の概要

この本の概要

本書は,Fluentdについて網羅的に解説した書籍です。

Fluentdは,ログやそのほかのデータの収集および集約,転送,変換,保存を実現するためのソフトウェアです。すでに多くのユーザーに利用されているほか,Kubernetes環境におけるデファクトスタンダードなログ収集方法として扱われています。そのため,AWS,GCPおよびAzureといったクラウド環境においても標準的なツールとして使われています。

本書は,Fluentdがデータをどのように処理しているかから,内部構造やプラグイン機構の詳細,プラグインの開発方法までを網羅的に記述しています。筆者はFluentdの初期からのユーザーであり,Fluentdの主開発者の一人でもあるため,ユーザーとして必要な事項を開発者の視点から解説できているはずです。

こんな方におすすめ

  • Fluentdについて学びたい方
  • ログやデータを扱うソフトウェアエンジニア,プログラマー,データエンジニア,ITインフラエンジニアやSRE

この書籍に関連する記事があります!

はじめに
本書は,Fluentdについて網羅的に解説した書籍です。ログやデータを扱うソフトウェアエンジニア,プログラマー,データエンジニア,ITインフラエンジニアやSREといった職種の人を対象とした,おそらく世界で初めてのFluentdのみについての技術書です。
Fluentdで多種多様なログ処理を行おう!
本書は、Fluentdがデータをどのように処理しているかから、内部構造やプラグイン機構の詳細、プラグインの開発方法までを網羅的に記述しています。筆者はFluentdの初期からのユーザーであり、Fluentdの主開発者の一人でもあるため、ユーザーとして必要な事項を開発者の視点から解説できているはずです。

目次

  • はじめに
  • 謝辞
  • 本書の読み進め方
  • 本書の前提知識
  • 対象バージョン
  • 動作環境
  • サポートページ

第1章:Fluentdとは何か

1.1 Fluentd ── 統合ログ基盤のためのデータ収集ツール

1.2 ログとは何か

  • ログの種類
    • システムログ ── コンピュータシステムの状況を記録する
    • アクセスログ ── Webサービスへのリクエストを記録する
    • アプリケーションログ ── コンピュータシステムで稼働するアプリケーションの挙動を記録する
    • 操作ログや行動ログ,IoTのログ ── より詳細にユーザーの挙動を記録する
  • 大規模データ処理の時代の到来
    • データ量とユースケースの急激な増大
    • 大規模データ処理のためのソフトウェアの登場

1.3 Fluentdの特徴

  • 柔軟なデータ配送 ── 入力元と出力先を自由に組み合わせる
    • 直接のデータ入出力
    • データ転送を挟んだ入出力
  • 構造化データ ── 扱う情報すべてに意味を持たせる
  • 豊富なプラグイン ── 多様な入出力と実行環境をサポートする
    • Fluentd登場以前の問題点
    • Fluentdによる解決
    • 公開プラグインのユーザー間での共有
  • 出力の並列化と再実行のしくみの提供 ── プラグインの実装を簡単にして開発を支援する

1.4 Fluentdのデータ処理方式

  • バッチ処理の問題点
    • データがまとまってから転送する
    • データがまとまってから処理する
  • ストリーム処理による解決
    • データを即座に転送する
    • データを即座に処理する
  • Fluentdで扱えるデータ

1.5 Fluentdのユースケース

  • ログ検索をすばやく実行
  • ログ集計によるモニタリングと通知の自動化
  • リアルタイムな状況分析
  • Fluentdを使用すべきでないケース

1.6 Fluentdのコア機能

  • ルーティング ── 行き先を制御する
  • バッファリング ── データを一時的に保存してまとめる
  • リトライ ── 失敗した処理をやりなおす
  • プラグイン機構 ── さまざまな機能を入れ替え可能にする

1.7 Fluentdのデータ配送方式

  • at most once ── 何もなければ成功とする
    • 採用するべきユースケース
  • at least once ── 成功したと返事がなければ失敗とする
    • 採用するべきユースケース
  • コラム:Fluentdでは未実装のexactly once ── 正確に1回だけ転送する

1.8 Fluentdのバージョン

1.9 本書の構成

1.10 まとめ

第2章:Fluentdのインストール

2.1 Fluentdの動作環境

  • Fluentdに必要なホスト性能

2.2 インストール前の準備

  • 時刻の同期の設定 ── NTPを用いて時刻を合わせる
  • システムリソース制限の変更 ── 多数のファイルを扱えるようにする
    • ファイルディスクリプタの設定
    • ネットワーク関連の設定
  • 実行内容の検討

2.3 インストール方法の選択

  • パッケージを用いたインストール
    • td-agent ── 歴史と実績の安定版
    • calyptia-fluentd ── 新世代の安定版
  • パッケージを用いないインストール
    • gem ── 手元環境でのFluentd利用に
    • ソースコード ── Fluentd本体の開発に

2.4 パッケージを用いたインストール

  • rpmパッケージ ── Red Hat Enterprise Linux,Amazon Linuxなど
    • td-agentのインストール
    • calyptia-fluentdのインストール
    • 設定ファイルの場所
    • 起動/停止方法
  • debパッケージ ── Ubuntu,Debian GNU/Linuxなど
    • td-agentのインストール
    • calyptia-fluentdのインストール
    • 設定ファイルの場所
    • 起動/停止方法
  • msiパッケージ ── Windows
    • td-agentのインストール
    • calyptia-fluentdのインストール
    • 設定ファイルの場所
    • 起動/停止方法

2.5 パッケージを用いないインストール

  • gem ── 手元環境でのFluentd利用に
    • Fluentdのインストール
    • 設定ファイルの場所
    • 起動/停止方法
  • ソースコード ── Fluentd本体の開発に
    • Fluentdのインストール
    • 設定ファイルの場所
    • 起動/停止方法

2.6 まとめ

第3章:Fluentdのシステム設定

3.1 Fluentdのシステム設定 ── Fluentdそのものの挙動を指定する

  • 動作方法関連のパラメータ
    • process_nameパラメータ ── プロセス名を指定する
    • workersパラメータ ── ワーカー数を指定する
    • without_sourceパラメータ ── Inputプラグインなしで起動する
    • enable_msgpack_time_supportパラメータ ── Timeオブジェクトを処理可能にする
    • strict_config_valueパラメータ ── パラメータ型のチェックを厳密に行う
    • restart_worker_intervalパラメータ ── ワーカープロセス再起動時に待ち時間を持つ
    • disable_shared_socketパラメータ ── プロセス間共有ソケットを使用しない
  • ファイルシステム関連のパラメータ
    • root_dirパラメータ ── プラグイン用ディスクスペースを指定する
    • file_permissionパラメータ ── ファイル作成時のデフォルトパーミッションを指定する
    • dir_permissionパラメータ ── ディレクトリ作成時のデフォルトパーミッションを指定する
  • ログ出力関連のパラメータ
    • log_levelパラメータ ── Fluentd全体のログレベルを指定する
    • suppress_config_dumpパラメータ ── ログへの設定ダンプを出力しない
    • suppress_repeated_stacktraceパラメータ ── 連続した同一エラーのスタックトレースを出力しない
    • log_event_verboseパラメータ ── 停止処理時にもログを出力する
    • emit_error_log_intervalパラメータ ── Inputプラグインのemit失敗ログの出力を抑制する
    • ignore_repeated_log_intervalパラメータ ── 連続して発生する同一ログの出力を抑制する
    • ignore_same_log_intervalパラメータ ── 同一ログの出力を抑制する
  • ログ出力関連の詳細パラメータ
    • formatパラメータ ── ログの書式を指定する
    • time_formatパラメータ ── ログの日時形式を指定する
    • rotate_sizeパラメータ ── ログファイルのサイズ上限を指定する
    • rotate_ageパラメータ ── 保持するログファイルの世代数を指定する
  • RPC関連のパラメータ
    • rpc_endpointパラメータ ── RPC操作用のエンドポイントを起動する
    • enable_get_dumpパラメータ ── 設定ダンプを出力するRPCエンドポイントを有効化する

3.2 Fluentdのコマンドラインオプション ── Fluentdをどのように起動するかを指定する

  • 使用可能なコマンドラインオプション
  • パッケージによるFluentdのコマンドラインオプション指定
    • Linuxでの環境変数を用いた指定
    • Windowsでのレジストリを用いた指定

3.3 設定変更の反映 ── 設定をFluentdに正しく読み込ませる

  • 全体の再起動による反映
  • 一部の再起動または再読み込みによる反映
    • ワーカープロセスの再起動による反映
    • ワーカープロセスからの設定再読み込みによる反映

3.4 シグナル,RPCによるプロセス管理 ── 動作中のFluentdを操作する

3.5 まとめ

第4章:設定ファイルの書式と構造

4.1 設定の構成要素 ── リテラル,パラメータ,ディレクティブ

4.2 リテラル ── 名前や値を表現する

  • リテラルの構造 ── さまざまな文字列
  • 空のリテラル ── 0文字の文字列
  • シングルクオートによるリテラル ── 空白や改行を含む文字列
  • ダブルクオートによるリテラル ── 特殊な処理が有効となる
    • バックスラッシュによるエスケープ文字
    • Ruby式の埋め込み

4.3 コメント ── 動作に影響しない注釈を書く

4.4 パラメータ ── 名前と型のある値の組み合わせを定義する

  • パラメータの構造 ── 名前と値の型を持つ
    • 名前 ── 何を設定するかを指定する
    • 値の型 ── パラメータが受け取る値の型を指定する
  • パラメータの型
    • 整数型,浮動小数点数型 ── 数値を表現する
    • サイズ型,時間型 ── 単位付き指定が可能な数値を表現する
    • 真偽値型 ── trueかfalseのどちらかを表現する
    • 文字列型 ── 文字の集合を表現する
    • 列挙型 ── 既定の値のどれかを表現する
    • 配列型 ── 複数の値を表現する
    • ハッシュ型 ── 複数の名前と値のペアを表現する
    • 正規表現型 ── 文字列のパターンを表現する
    • レコードのキーを表すパラメータ
  • パラメータのデフォルト値

4.5 ディレクティブ ── 構造を決定する要素

  • ディレクティブの構造 ── パラメータの集合をタグで囲む
    • タグ ── ディレクティブの種類を定義する
    • 引数 ── ディレクティブに情報を追加する
    • パラメータ ── ディレクティブ単位で有効な設定を指定する
    • セクション ── 設定値を与えられたディレクティブを表す
  • 既定のディレクティブ ── Fluentd本体に必須の機能を実現する
    • <system>ディレクティブ ── Fluentd全体を設定する
    • <worker>ディレクティブ ── 個別のワーカーを設定する
    • <source>ディレクティブ ── Inputプラグインを設定する
    • <match>ディレクティブ ── Outputプラグインを設定する
    • <filter>ディレクティブ ── Filterプラグインを設定する
    • <label>ディレクティブ ── ラベルの付いたイベントをルーティングする
    • そのほかのディレクティブ ── プラグインに機能を提供する

4.6 <source>,<match>,<filter>ディレクティブの予約語パラメータ

  • @typeパラメータ ── 使用するプラグイン名を指定する
  • @idパラメータ ── プラグイン設定にIDを付けて判別可能にする
  • @log_levelパラメータ ── プラグイン単位でログレベルを指定する
  • @labelパラメータ ── イベントのルーティング制御用ラベルを指定する

4.7 @include ── 設定ファイルにほかのファイルの記述を取り込む

  • 各サーバへの共通設定の取り込み
  • 各プラグインへの共通パラメータの取り込み
  • URLを用いたHTTP経由での取り込み

4.8 設定ファイルの全体像

4.9 まとめ

  • コラム:YAMLによる設定ファイル記述

第5章:プラグインの基本

5.1 Fluentdにおけるプラグイン ── Fluentdの主要な機能を実現する

5.2 プラグインのライフサイクル ── 初期化から起動,停止,破棄まで

5.3 プラグインの種類

  • プラグイン名のルール ── 種類と名前の組み合わせからなる
  • プラグインの機能による分類
    • オーナープラグイン ── イベント処理の中心となるInput,Filter,Outputプラグイン
    • オウンドプラグイン ── プラグインから使われるそのほかのプラグイン
  • プラグインヘルパー ── プラグインに共通の機能を提供する

5.4 プラグインのインストール

  • RubyGemsによるインストール ── 公開されているプラグインをインストールする
  • コマンドライン指定またはディレクトリ配置によるインストール ── 1ファイルだけのプラグインを読み込ませる
  • Gemfileによる管理 ── 使用するプラグインとそのバージョンをまとめて指定する

5.5 プラグイン探索のしくみ

  • プラグインのファイル名のルール ── 種類のための接頭辞を持つ
  • プラグイン探索の優先順位

5.6 まとめ

第6章:イベントデータ

6.1 Fluentdにおけるイベント ── タグ,日時とレコードからなる

6.2 イベントの構造

  • タグ ── データの発生元や種類を表現する
    • タグはドット区切りの文字列
    • タグの設計方針
  • 日時 ── データがいつ発生したかを示す
    • ナノ秒精度による日時
    • タイムゾーンへの配慮の必要性
  • レコード ── 伝達すべきデータの内容そのもの
    • キーと値のペアの集合によるデータ表現
    • レコードの大きさの制約

6.3 イベントの流れ

  • イベントの基本的な流れ ── Inputプラグインにより入力され,Outputプラグインにより出力される
    • Inputプラグインによるイベントの生成
    • Routerによるイベントのルーティング
    • ラベルを用いたイベント処理内容の定義
    • Filterプラグインによるイベントの処理
    • Outputプラグインによるイベントの出力
  • そのほかのイベントの流れ
    • Outputプラグインによる例外的なイベント生成
    • エラーストリーム ── 正常に処理できないイベントの行き先
    • ログストリーム ── Fluentd自身のログもイベントとして扱う

6.4 プラグインによるデータ処理

  • データの入力と取り込みに関わるプラグイン
    • Inputプラグイン ── データを入力する
    • Parserプラグイン ── テキストデータを解析する
    • extractプラグインヘルパー ── タグや日時をレコードから抽出する
  • データの書式と出力に関わるプラグイン
    • Outputプラグイン ── データを出力する
    • Formatterプラグイン ── データの書式を変更する
    • injectプラグインヘルパー ── タグや日時をレコードに注入する
  • データの処理を行うプラグイン
    • Filterプラグイン ── データの除去や付加,変更を行う

6.5 Fluentdのプロセスとイベント処理

  • Fluentdのプロセス構成 ── スーパーバイザーとワーカー
    • プロセス管理を行うスーパーバイザープロセス
    • データ処理を行うワーカープロセス
  • 実行プロセス名の変更
  • 複数ワーカー ── 複数プロセスの利用により処理性能を引き上げる
    • 複数ワーカーによるデータ処理
    • プラグインごとの複数ワーカー対応
    • 複数ワーカー動作に非対応のプラグインの使用

6.6 MessagePack ── Fluentdが使用するイベントデータ表現方法

  • 効率的なデータ表現の必要性
    • バッファリングのための高いデータ読み書き性能
    • ネットワーク転送に伴う高効率なデータ変換
  • 一般的な手法であるJSONの問題点 ── 低いサイズ効率
  • MessagePackによる解決 ── バイナリによる効率的なデータ表現

6.7 まとめ

第7章:プラグインごとの役割

7.1 さまざまな種類のプラグイン

7.2 Inputプラグイン ── データの入力を担当する

  • Inputプラグインが実行する処理
  • Inputプラグインによるイベント生成
    • タグの付与
    • 日時の生成
    • レコードの生成
  • @labelパラメータによるルーティング先の決定
  • イベント生成を行う複数のemitメソッドと性能特性

7.3 Filterプラグイン ── InputプラグインとOutputプラグインの間でデータを加工する

  • Filterプラグインが実行する処理

7.4 Outputプラグイン ── データの出力を担当する

  • Outputプラグインが実行する処理
  • バッファリングの有無
    • バッファリングを行わない非バッファOutputプラグイン
    • バッファリングを行うバッファOutputプラグイン
  • スレッド ── 出力処理を入力から分離し,並列化する
    • スレッド設定の考え方
  • バッファチャンク ── チャンクキーごとにデータをまとめる
    • チャンクキーの省略 ── 全データがまとめて書かれる
    • キャンクキーへのタグや日時の指定 ── 同じタグや時間でまとめる
    • 複雑なチャンクキーの指定
  • プレースホルダ展開 ── チャンクキーの情報を出力にも用いる
    • 日時のためのプレースホルダ
    • タグやレコード中の値のためのプレースホルダ
    • そのほかの特殊なプレースホルダと組み合わせ
  • flushパラメータとチャンクサイズ ── データ出力の粒度と頻度を制御する
    • flush_modeパラメータによる詳細な出力の制御
  • flush_threadパラメータ群 ── データ出力の頻度と並列度を制御する
    • flush_thread_countパラメータ ── 出力の並列数を指定する
    • flush_thread_intervalパラメータ ── 出力処理の間隔を指定する
    • flush_thread_burst_intervalパラメータ ── 連続したデータ出力を抑止する
    • flush_threadパラメータ群の関係
  • retryパラメータ ── 出力処理のリトライを制御する
    • exponential_backoff ── 標準のリトライ方法
    • periodic ── よりわかりやすいリトライ方法
    • リトライ設定における注意点
    • リトライがいつまでも成功しない場合の処理
  • Secondary Output ── 回復不能なエラーに対処する
    • Outputプラグインが出力に失敗し続ける場合のための機能
    • 出力失敗時の最後の手段として使用
  • Multi Outputプラグイン ── 複数のOutputプラグインへ出力する特殊なOutputプラグイン
    • out_copyとout_roundrobinプラグインに見るMulti Outputプラグインの典型例

7.5 Bufferプラグイン ── データのバッファリング機構をOutputプラグインに提供する

  • Bufferプラグインが実行する処理
  • 2つのBufferプラグイン ── 保存場所としてメモリかファイルかを選択する
    • memory ── メモリ空間にデータを保存する
    • file ── 指定したパスのファイルにデータを保存する
    • memoryとfileの選択基準
    • fileに特有の注意点
  • flush_at_shutdownパラメータ ── Fluentd停止時にデータを出力する
  • チャンクサイズの制御
    • チャンクサイズのレコード数による制御
  • バッファ総容量の制御
    • バッファ総容量を使い切った場合の処理
    • 圧縮オプションによるバッファ使用容量の削減

7.6 Parserプラグイン ── データを解析する

  • Parserプラグインが実行する処理
  • Parserによる日時解析
  • Parserによる型変換
  • Parserが空だと判断する値の指定

7.7 Formatterプラグイン ── イベントをテキストデータに整形する

  • Formatterプラグインが実行する処理
  • Formatterによる日時変換

7.8 Storageプラグイン ── プラグインのための保存機能を提供する

  • Storageプラグインが実行する処理

7.9 Service Discoveryプラグイン ── 連携先サービスを管理する

  • Service Discoveryプラグインが実行する処理

7.10 まとめ

第8章:組込みプラグイン

8.1 さまざまな組込みプラグイン

8.2 in_tailプラグインとParserプラグイン ── テキストファイルからデータを読み込む

  • ログの読み込み設定
    • 1行単位のログの読み込み
    • 複数行からなるログの読み込み
    • 長すぎる行の無視
  • さまざまなファイルパス指定 ── 読み込み対象を柔軟に指定する
    • ワイルドカードによる複数ファイルの並行読み込み
    • 日時パターンによる日付などを含むファイル名ログの継続的な読み込み
    • 複数ファイルを対象にしたファイルの先頭からの読み込み
  • 読み込みの停止と再開
  • ログローテーション時のin_tailプラグインの挙動
    • ログローテーション後のもとのファイルの監視
    • ログローテーション後の新規ファイル作成の検出
    • ワイルドカード使用時のログローテーション
  • アクセス権限のトラブル ── ファイルの読み込み権限と,再開位置に必要な書き込み権限

8.3 out_fileプラグインとFormatterプラグイン ── データをテキストファイルに書き出す

  • 書き出し単位およびデータ形式の指定
    • タグや日時を含んだファイル名での書き出し
  • ファイル単位での書き出しおよび追記
  • 圧縮ファイルでの書き出し
  • out_fileプラグインによる出力ファイルの外部からの監視

8.4 in_forward/out_forwardプラグイン ── ネットワーク経由でデータを送受信する

  • ホスト間でのデータのやりとり
  • at least onceによる確実な送信
    • at least onceでの通信パターン
    • at least onceでのデータ送信のデメリット
  • データ送信先の管理方法
    • データ送信先の設定ファイルでの管理
    • データ送信先のService Discoveryプラグインでの管理
    • sd_fileプラグインによるService Discoveryプラグインの使用例
  • 通信の暗号化 ── TLSによる暗号化通信でデータを送る
    • 暗号化のためのサーバ証明書の準備
    • 事前共有した証明書をCAとしてのサーバ証明書の生成
  • 送受信の相手の相互認証
    • 共有キーによる送受信相互の認証
    • ユーザー名とパスワードによる送信者の認証
  • キープアライブの利用 ── 確立した接続を再利用して接続負荷を削減する
  • HeartbeatのUDP利用 ── 通信負荷を削減する
  • 受信したデータの制御
    • ラベルによる受信データ処理方法の制御
    • 受信データのタグの変更
    • 受信データへの送信元情報の追加
    • 安全に扱えない受信データの無視

8.5 out_copyプラグイン ── 複数のプラグインとの組み合わせでデータを別々に処理する

  • ほかのOutputプラグインとの組み合わせ例
    • out_stdoutプラグイン ── データの中身を確認する
    • out_relabelプラグイン ── データを別のパイプラインへ分岐する
  • copy_modeパラメータ ── 他プラグインの影響を排除する
    • 単純なコピーによるレコードへの変更の回避
    • 深いコピーによるレコードの値への変更の回避
  • 出力エラーの扱いの変更 ── プラグインによる処理失敗を無視する
    • ignore_errorオプション ── 特定プラグインでの失敗を無視する
    • ignore_if_prev_successオプション ── 前プラグインが失敗したときに出力を実行する

8.6 filter_grepプラグイン ── 正規表現を用いてデータを選別する

  • 条件に合うイベントの選別
  • 条件に合うイベントの除去
  • 選別と除去,andとorを組み合わせた複雑な条件の記述
  • 深い階層構造を持ったレコードの処理

8.7 filter_parserプラグイン ── レコード内のデータをさらに解析する

  • データの取り出し ── レコードの値に含まれる情報をレコードとする
  • イベントの更新 ── レコードの値に含まれる情報をレコードに加える
  • filter_record_transformerプラグイン ── 独自のルールやRubyコードを用いてさらに複雑な処理を実現する

8.8 in_exec/out_execプラグイン ── 外部コマンドの実行によるデータの入出力

  • in_execプラグイン ── コマンド実行結果を取り込む
    • 起動後に継続的にデータを出力するコマンドの利用
    • 定期的なコマンド実行からのデータ取り込み
  • out_execプラグイン ── コマンド実行によりデータを出力する
    • データ出力の実行時間の制御

8.9 in_http/out_httpプラグイン ── HTTP通信によるデータの入出力

  • HTTPリクエストによる外部からのデータ受信
    • リクエストヘッダやクエリパラメータの値のレコードへの追加
    • クロスオリジンリクエストの受信
    • 任意の形式を用いたHTTPでのデータ受信
  • HTTPリクエストとしての外部へのデータ送信
    • 1つのJSONオブジェクトとしてのリクエストボディ
    • Content-Typeや任意のリクエストヘッダの指定
    • HTTPリクエストの失敗のコントロール

8.10 まとめ

第9章:本番環境における構成と運用

9.1 本番環境における難しさ

9.2 データの収集と集約における戦略

  • 規模の拡大と権限および認証情報管理の両立
  • エージェント ── データ発生元からデータを読み込む
  • 集約ノード ── エージェントからデータを集めて書き込む
    • 集約ノードによる性能と運用性の向上
    • 集約ノードの冗長化
  • コンテナからのログ収集
    • ファイルを経由したログ収集
    • DockerのLogging Driverを経由したログ収集
    • Fluentdをコンテナで動かしてのログ収集

9.3 エージェントにおけるFluentd設定の注意点

  • CPUやメモリなどのリソース消費の抑制
  • エージェントのディスクスペースへの上限設定
    • プラグインごとのバッファの最大使用サイズ
  • ネットワークへの過負荷の防止
  • Fluentdの停止順序制御 ── ログ出力元よりもあとにFluentdを停止する

9.4 集約ノードにおけるFluentd設定の注意点

  • サーバ性能を活かせるようなパラメータ設定
  • 集約ノードのディスクスペースの設計と制御
    • 必要なローカルディスクの総容量を見積もる
    • ディスク使用量を考えたパラメータ設定
  • 常に余裕を持たせたネットワーク帯域
    • 高スループットなデータ出力のための設定と設計
  • 複数の集約ノードへの分散データ転送
    • out_forwardプラグインによる分散データ転送
    • 複数の集約ノードへのデータ転送におけるロードバランサの利用
    • ロードバランサによる暗号化の組み合わせ

9.5 コンテナにおけるFluentd設定の注意点

  • ファイルの所有権とパーミッションの確認
  • コンテナの終了順序の指定
  • コンテナ外を利用したファイルバッファ

9.6 バッファ管理のための設定とオプション

  • flush_at_shutdownパラメータ ── 停止時にローカルストレージにファイルを残さない
  • without-sourceコマンドラインオプション ── 残ったバッファを出力するためにFluentdを起動する
    • サーバシャットダウン処理としてのバッファ出力用の起動

9.7 実運用のためのFluentdログ設定

  • ログレベル変更によるFluentdログの制御
    • Fluentd全体のログレベルの変更
    • プラグイン単位のログレベルの変更
  • 同内容のエラーログの出力量の制御
    • 連続した同じスタックトレースの非表示化
    • 一定時間内の同内容ログの非表示化

9.8 Fluentdの監視

  • in_monitor_agentプラグインによる監視
    • 外部からの監視リクエストへの応答
    • 外部への動作状況の報告

9.9 設定ファイルとプラグインの管理手法

  • @includeによる設定ファイルの用途ごとの分割と共有
    • 設定ファイルの読み込み順序の明示
  • Gemfileによるプラグインの一括管理
  • DockerによるFluentdとプラグイン,設定の一括管理

9.10 まとめ

第10章:プラグイン開発の基本

10.1 プラグイン開発の必要性

10.2 プラグイン開発チュートリアル ── 簡単なプラグインを書いてみる

  • 最小限のプラグイン作成
    • プラグインファイルの作成
    • プラグインを使用する設定ファイルの作成
    • 作成したプラグインの読み込みと起動
  • 一定間隔でのレコード生成の実装
    • プラグインヘルパーを用いた一定時間ごとの処理実行
    • 変更した処理内容の確認
  • パラメータによる設定の利用
    • 文字列のためのパラメータ追加
    • 追加したパラメータの設定ファイルにおける指定
  • チュートリアルのふりかえり

10.3 プラグイン開発の流れ

  • プラグインのgemパッケージ化の考慮
  • gemパッケージの初期作成
    • fluent-plugin-generateコマンドによるファイル生成
    • bundle gemコマンドによるファイル生成
  • gemspecへのgem情報の記述
    • プラグイン情報の編集
    • 依存ライブラリの指定
  • プラグインコードの記述
  • テストの記述
    • テストによるプラグインに期待する動作の明示
    • テストの継続的な実行による挙動の確認
    • 教材としての他プラグインのテストコード
  • バージョン管理 ── バージョン番号を付けて更新する
    • プラグインリリース時の初期バージョン
    • プラグインをバージョン1.0にする時期
  • リリース ── プラグインを必要な場所で動かせるようにする
    • 非公開gemとする場合のリリース
    • RubyGemsを通して公開する場合のリリース
    • リリースはユーザーに対するコミュニケーション

10.4 プラグイン共通の処理

  • プラグインの設定パラメータ
  • プラグインライフサイクル ── プラグイン起動時や停止時に処理を実行する
    • 必要なライフサイクルの選択と実装
    • ライフサイクルメソッドにおけるsuper呼び出し
  • プラグインヘルパー ── Fluentdが用意する共通の機能を呼び出す
    • プラグインヘルパーの使用宣言
    • ライフサイクルメソッドにおけるsuper呼び出し
  • プラグインIDの確認と利用 ── 動作中のプラグイン固有の情報を使う
  • プラグインルートディレクトリ ── プラグインのためのファイル置き場を使う
    • プラグインルートディレクトリ使用時の注意点
    • Storageプラグインによるプラグインデータ保存の検討
  • 複数ワーカー対応 ── 複数のFluentdプロセスでプラグインを動作させる
    • 複数ワーカーに対応したプラグインの作成
    • 設定による複数ワーカー対応の可否
  • プラグインロガー ── プラグインの動作状況を記録する
    • プラグインロガーの使用方法
    • キーワード引数を用いた付加情報の付与
    • ブロックを用いた付加情報の付与
    • errorキーワードによる例外のロギング
    • ログ出力の重要性

10.5 まとめ

第11章:プラグインの設定

11.1 プラグインの設定方法 ── パラメータとセクションを使用する

11.2 パラメータの定義と利用

  • パラメータ ── 設定をオブジェクト化する
  • config_paramメソッド ── パラメータを定義する
    • パラメータの名前と型の指定
    • パラメータのオプションの指定
    • パラメータの値の利用
  • パラメータの型
    • integer,float ── 整数と浮動小数点数
    • size,time ── 単位を指定できる数値
    • bool ── 真か偽の値
    • string ── 任意の文字列
    • enum ── シンボルの選択肢
    • array ── 値の配列
    • hash ── キーと値のペア
    • regexp ── 文字列のパターン
  • 型破りなパラメータ ── 型のみでは定義できない設定値を使う
    • 型を明示しないパラメータの定義と使用
    • 困ったときの文字列パラメータ
  • パラメータのオプション
    • defaultオプション ── 無指定の場合のデフォルト値を指定する
    • secretオプション ── 設定値をログに表示しないよう秘密にする
    • param_nameオプション ── プラグインコード内では設定名と異なる名前を使う
    • aliasオプション ── 設定ファイル内でのパラメータの別名を使えるようにする
    • deprecatedオプション ── もう使用しないでほしいパラメータを示す
    • obsoletedオプション ── パラメータを使用禁止だと宣言する
    • descオプション ── パラメータの説明を記述する
  • config_set_defaultメソッド ── デフォルト値を上書きする
    • デフォルト値の上書きの利用ケース

11.3 セクションの定義と利用

  • セクション ── ディレクティブをオブジェクト化する
  • config_sectionメソッド ── セクションを定義する
    • セクションの名前とパラメータの指定
    • セクションの引数の指定
    • セクションオブジェクトの利用
  • セクションのオプション
    • requiredオプション ── 指定必須のセクションを作る
    • multiオプション ── 同名セクションを複数指定可能にする
    • initオプション ── 設定ファイルで指定されなくてもセクションオブジェクトを作る
    • finalオプション ── セクション定義を上書き不可能にする
    • param_nameオプション ── プラグインコード内では設定名と異なる名前を使う
    • aliasオプション ── 設定ファイル内でのディレクティブの別名を使えるようにする

11.4 プラグインによる設定の解析と利用

  • configureメソッド ── プラグインを設定する
    • プラグイン設定解析の詳細
    • 設定値の追加チェックの実装
  • 設定値を用いたプラグイン起動の準備

11.5 まとめ

第12章:プラグインごとの開発手順

12.1 Inputプラグインの開発

  • Inputプラグインの形式
  • データの取り込み
    • Routerを経由するデータ取り込み
    • router.emitメソッドに渡すタグと日時,レコード
    • 読み取ったデータの日時や種別の扱い
  • 複数イベントの効率的なemit
    • 同一タグのイベントに対するemit_arrayメソッドの使用
  • Inputプラグインにおけるパターン
    • 定期的な処理実行
    • ネットワーク経由でのデータ受信

12.2 Filterプラグインの開発

  • Filterプラグインの形式
    • 日時操作の有無による実装の違い
  • イベント内容の変更 ── レコードや日時を更新する
    • レコードの変更
    • 日時の変更
  • イベントの破棄 ── 特定の条件に合わせてイベントを破棄する
    • 破棄されたイベントのエラーストリームへの出力
  • Filterプラグインに期待しない処理

12.3 Outputプラグインの開発

  • Outputプラグインの形式
  • Outputプラグインの動作モード
    • バッファOutputプラグイン ── バッファにためたデータをまとめて外部に書き出す
    • 非同期バッファOutputプラグイン ── まとめたデータ書き出しの結果を別途確認する
    • 非バッファOutputプラグイン ── データが来たら即座に書き出す
  • バッファOutputプラグインの実装
    • バッファリングの単位となるバッファチャンク
    • バッファチャンク内のデータ
    • バッファチャンクに対して可能な操作
    • バッファチャンクのメタデータの利用
    • バッファチャンクのユニークIDを用いたデータ処理の追跡
    • バッファチャンク単位での出力先の変更
    • バッファチャンクのデータ形式変更
  • 非同期バッファOutputプラグインの実装
    • 非同期バッファのバッファチャンクの扱いは同期バッファと共通
    • 出力時の書き出しごとのID付与
    • 書き出し結果確認後のコミット
    • 非同期バッファによる強固なデータ保護の実現
  • 非バッファOutputプラグインの実装
    • 自力での例外処理の実施
    • 失敗を許容するケースでの利用
  • Outputプラグインの動作モード決定ルール
  • 正常に出力できないイベントのエラーストリームへの出力

12.4 Parserプラグインの開発

  • Parserプラグインの形式
  • Parserプラグインによるデータからの複数のイベント取り出し
  • Parserプラグインが共通で提供する機能

12.5 Formatterプラグインの開発

  • Formatterプラグインの形式
  • Formatterプラグインが共通で提供する機能

12.6 まとめ

第13章:プラグインのテスト

13.1 テスト記述の方法

  • テストの流れ
    • 最小限のテストコード記述
    • テストの準備と実行
    • 実行と修正の繰り返し
  • テストコードの書き方
    • 公開プラグインのテストの参照

13.2 Inputプラグインのテスト

  • イベント生成の正しい検証
    • 動作検証前の特定の処理の実行
    • プラグインの起動や停止処理の省略
  • 入力イベントの検査に使用できるメソッド
    • eventsメソッド ── イベントを返す
    • record_countメソッド ── イベントの数を返す
    • event_streamsメソッド ── イベントストリームを返す
    • emit_countメソッド ── emitした回数を返す

13.3 Filterプラグインのテスト

  • イベントに対するフィルタ結果の検証
  • Filterプラグインのテストにおけるタグの扱いの省略

13.4 Outputプラグインのテスト

  • モックを使った出力の検証
  • 出力の検証方法を決めてからのテスト記述

13.5 Parserプラグインのテスト

  • 1回の呼び出しで複数レコードが返る場合の想定

13.6 Formatterプラグインのテスト

13.7 テスト記述のためのヘルパーメソッド

  • event_timeメソッド ── 望みの日時オブジェクトを簡単に生成する
  • with_timezoneメソッド ── タイムゾーンを変更する
  • with_worker_configメソッド ── 複数ワーカーでの動作をシミュレートする
  • capture_logメソッド ── プラグインからのログ出力を取得する

13.8 まとめ

第14章:プラグインヘルパー

14.1 さまざまなプラグインヘルパー

14.2 プラグインヘルパーの使用方法

  • プラグインヘルパーの有効化 ── プラグインで使用する機能を宣言する
  • プラグインヘルパーのメソッド呼び出し
  • プラグインヘルパーメソッドの説明例

14.3 timerプラグインヘルパー ── 一定時間ごとに処理を実行する

  • timer_executeメソッド ── ブロック引数の処理を一定時間ごとに実行する

14.4 child_processプラグインヘルパー ── 外部コマンドを子プロセスとして実行する

  • child_process_exist?メソッド ── 子プロセスが実行中かどうかを返す
  • child_process_executeメソッド ── 指定コマンドを子プロセスとして実行する
    • 単純な外部コマンドの起動
    • 起動した外部コマンドとの間での入出力
    • 外部コマンドとの入出力におけるエンコーディング変換
    • ブロック付き呼び出しとプロセスの終了

14.5 serverプラグインヘルパー ── ネットワークサーバを作成する

  • server_createメソッド ── ネットワークサーバを作成して起動する
    • ユーザーが設定したプロトコルの使用
    • コネクションを使用したメッセージ返信
    • 複数ワーカー動作への対応
    • UDPデータ送信に対する返信の受信
    • システムに依存する低レベルオプション
  • server_create_connectionメソッド ── コネクション確立を検出するサーバを作成する
    • 確立した接続に対する操作

14.6 http_serverプラグインヘルパー ── HTTPサーバを作成する

  • http_server_create_http_serverメソッド ── HTTPサーバを作成して起動する
    • リクエストパスごとの処理の記述
    • デフォルトの処理
  • http_server_create_https_serverメソッド ── HTTPSサーバを作成して起動する

14.7 threadプラグインヘルパー ── スレッドを作成する

  • thread_createメソッド ── スレッドを作成して開始する
  • thread_current_running?メソッド ── 現在のスレッドが実行中状態かどうかを返す
  • thread_wait_until_startメソッド ── すべてのスレッドが実行中になるまで待つ
  • thread_wait_until_stopメソッド ── すべてのスレッドが停止するまで待つ

14.8 socketプラグインヘルパー ── ソケットを作成する

  • socket_create_tcpメソッド ── TCPソケットを作成して接続する
  • socket_create_udpメソッド ── UDPソケットを作成する
  • socket_create_tlsメソッド ── TLSソケットを作成して接続する
  • socket_createメソッド ── 指定プロトコルでソケットを作成する

14.9 injectプラグインヘルパー ── タグや日時などを注入する

  • inject_values_to_recordメソッド ── タグや日時などをレコードに注入する
  • inject_values_to_event_streamメソッド ── タグや日時などをイベントストリームに注入する

14.10 extractプラグインヘルパー ── レコードからタグや日時を取り出す

  • extract_tag_from_recordメソッド ── レコードからタグを取り出す
  • extract_time_from_recordメソッド ── レコードから日時を取り出す

14.11 formatterプラグインヘルパー ── データ文字列のためFormatterプラグインを作成する

  • formatter_createメソッド ── Formatterプラグインを作成する
    • プラグインによるFormatterプラグインのデフォルト指定
    • 用途ごとに異なる複数のFormatterプラグインの作成
    • 作成したプラグインの利用

14.12 parserプラグインヘルパー ── 文字列を解析してデータを得るためParserプラグインを作成する

  • parser_createメソッド ── Parserプラグインを作成する
    • プラグインによるParserプラグインのデフォルト指定
    • Parserプラグインのブロック付き呼び出し

14.13 record_accessorプラグインヘルパー ── 複雑な構造のレコードにアクセスする

  • record_accessor_createメソッド ── 指定要素へのアクセサオブジェクトを作成する

14.14 storageプラグインヘルパー ── プラグインから使用可能なストレージを提供する

  • storage_createメソッド ── Storageプラグインを作成する
    • ストレージに対するデータ操作

14.15 service_discoveryプラグインヘルパー ── サービスの情報をプラグインに対して提供する

  • service_discovery_configureメソッド ── Service Discoveryプラグインのセットアップを行う
    • 専用のディレクティブに設定された情報の参照
    • 固定リストの専用ディレクティブによる指定
    • サービスオブジェクトのプラグイン側オブジェクトへの変換
    • サービスの選択方法の制御
  • service_discovery_select_serviceメソッド ── 利用可能サービスを1つ選択する
  • service_discovery_servicesメソッド ── 利用可能サービスをすべて返す
  • service_discovery_rebalanceメソッド ── サービスのリバランスを行う

14.16 counterプラグインヘルパー ── 内部用カウンタを提供する

  • Counter API ── Fluentdプロセス間で共有されたカウンタの操作
    • カウンタによる数値の保存
    • クライアントを経由したカウンタ操作
    • Counter API有効化に必要な設定
  • counter_client_createメソッド ── Counter APIクライアントを作成する
    • カウンタ操作の同期実行と非同期実行
    • カウンタの初期化
    • カウンタの取得
    • カウンタの増加
    • カウンタのリセット
    • カウンタの削除

14.17 event_emitterプラグインヘルパー ── プラグインからイベントを入力する

  • routerメソッド ── Routerを返す

14.18 まとめ

第15章:Fluentdの通信プロトコル

15.1 ネットワーク通信プロトコルの重要性

15.2 Fluentd forward protocol v1の概要 ── 通信路とデータ表現

  • プロトコルのバージョン
  • TCPまたはTLSを用いた通信
  • MessagePackによるデータ表現
  • データ転送のためのモード
    • Messageモード ── 一度に1イベントのみを送る
    • Forwardモード ── 複数のイベントをまとめて送る
    • PackedForwardモード ── 処理効率の良いデータ表現を用いて送る
    • CompressedPackedForwardモード ── 圧縮済みのデータを送る
  • 日時の表現
    • ナノ秒精度の値を用いたFluentdの日時
    • 2つの整数を組み合わせた日時表現
  • 通信オプション
    • sizeオプション ── データがいくつイベントを保持するか示す
    • chunkオプション ── データ送信に対してACKを要求する
    • compressedオプション ── データの圧縮形式を指定する

15.3 Heartbeatを用いた死活監視 ── データ送信先が正常か確認する

  • FluentdにおけるHeartbeat
  • in_forward/out_forwardプラグインにおける実際の死活監視

15.4 ACK ── データを受信したことを送信元に通知する

  • ACKを要求するデータ転送
  • ACK要求された場合のレスポンス

15.5 認証 ── 送信元あるいは送信先は正しいかを確認する

  • データ送信前の認証作業
    • 共有キーによるサーバとクライアントの相互認証
    • ユーザー名とパスワードによるクライアント認証
  • サーバのHELOメッセージ ── 認証処理に必要な情報を伝える
    • 通常の場合
    • クライアント認証を要求する場合
  • クライアントのPINGメッセージ ── クライアントから認証情報を送る
  • サーバのPONGメッセージ ── 認証結果とサーバからの認証情報を返す

15.6 TLSによる暗号化通信 ── 送信データを暗号化により守る

  • TLSのメリットとデメリット
  • TLSのデメリットを緩和するキープアライブ

15.7 まとめ


  • あとがき
  • 索引
  • 著者プロフィール

著者プロフィール

田籠聡(たごもりさとし)

プログラマーとしてlivedoor,LINE,Treasure Dataなどで働いたのち,現在は独立してサービス開発や技術顧問などを行う。データ分析基盤関連のほか,WebアプリケーションやITインフラなどの技術にも携わる。ほかにISUCONの発案と発起など。Fluentdを含む多数のOSSプロジェクトのコミッター,メンテナー。