IoTや組み込み向けのデータコレクタ、FluentBitについて

FluentBitとは

IoT機器や組み込み機器を対象としたオープンソースのデータコレクタです。名前から分かる通り、Fluentdの兄弟アプリで、Treasure Dataのエンジニアが中心となって開発が進められています。 このソフトでは、例えば、

  • 定期的にCPU使用率を取得し、標準出力に出力する
  • カーネルログを取得し、外部のFluentdサーバに送信する
  • センサファイルから定期的に状態を読み出し、HTTP経由で外部に送信する

といったことが可能です。

名前はFluent-Bitだったり、Fluent Bitだったり、FluentBitだったり、様々な記載が見受けられます。

特徴

本家のFluentdと比べて次のような特徴があります。

  • C言語で実装されているため、Rubyが無い環境でも動作する
  • 軽量・高速(らしい)*1
  • C API経由で自前のアプリからデータを流せる/受け取れる
  • ビルドオプションで様々にカスタマイズ可能(Plugin削減やクロスコンパイルなど)

どう使うか

IoT機器のデータをFluentdに集める用途に使われるのではないでしょうか。in_libin_headでセンサデータを取得し、out_forwardで送信する使い方です。Fluentdに一旦送信できれば、強力で多彩なFluentdのOutput Pluginを使い、より多様な送信先にセンサデータを転送できるので。

Input Plugin

2016年9月現在、下記のプラグインがサポートされています。

  • in_cpu : CPU使用率
  • in_mem : メモリ使用量
  • in_kmsg : カーネルログバッファ(/dev/kmsg)
  • in_serial: シリアル入力
  • in_stdin: 標準入力
  • in_mqtt : MQTT
  • in_head : ファイル
  • in_xbee : xbee
  • in_forward : Fluentdプロトコル
  • in_random : ランダム値を生成
  • in_lib : C API経由でデータをPushするために使う

Output Plugin

2016年9月現在、下記のプラグインがサポートされています。

  • out_es : Elasticsearch
  • out_forward : Fluentdプロトコル
  • out_http : HTTP出力
  • out_null : データ破棄用
  • out_stdout : 標準出力
  • out_td : Treasure Data
  • out_nats : NATS用
  • out_lib : C API経由でデータを取得するために使う

使い方1: コマンドとして使う

後述のビルドを行うと、fluent-bitという実行ファイルが生成されます。使い方はシンプルで-iで入力元を、-oで出力先を指定し、実行するだけです。

例えば、CPU使用率を標準出力に出力する場合は、下記のようになります。

$ fluent-bit -i cpu -o stdout

Fluentdのように、ネットワーク経由の場合は下記のようにサーバ名やポートを指定できます。

$ fluent-bit -i cpu -o forward://127.0.0.1:12225

-cオプションを使うことでコンフィグファイルを食わせて実行させることもできます。confディレクトリにサンプルが含まれているので確認してみて下さい。

$ fluent-bit -c fluent-bit.conf

Fluentdとはフォーマットが異なりますが、下記のような内容になります。[INPUT][OUTPUT]はPluginごとに指定可能なパラメータが異なるので、詳しくは公式Documentを参照してください。

[SERVICE]
    Log_Level    info
    Flush        5

[INPUT]
    Name cpu
    Tag  cpu.local

[OUTPUT]
    Name  stdout
    Match **

使い方2: 共有ライブラリとして使う

FluentBitは共有ライブラリとしても提供されている為、他のアプリケーションからFluentBitに一度ログを送信し、FluentBitからFluentdに送信してもらう、といった使い方が可能です。 C APIからデータを入力/出力するには、それぞれin_libout_libプラグインを使用します。

下記のAPIが公開されています。

  • コンテキスト生成
  • プラグインの有効化
  • プラグイン設定
  • サービス開始
  • データをPushする
  • サービス終了
  • コンテキスト破棄

in_lib経由で自前のデータをPushし、out_libに登録したコールバック関数my_stdoutでデータを受け取り標準出力に出力するサンプルです。

#include <unistd.h>
#include <fluent-bit.h>
#include <msgpack.h>

/* out_lib用のコールバック関数 */
int my_stdout(void* data, size_t size)
{   
    printf("[%s]",__FUNCTION__);
    msgpack_object_print(stdout, *(msgpack_object*)data);
    printf("\n");

    /* User has to release the buffer. */
    free(data);

    return 0;
}

int main()
{
    int i;
    int n;
    char tmp[256];
    flb_ctx_t *ctx;
    flb_input_t *input;
    flb_output_t *output;

    /* Initialize library */
    ctx = flb_create(); /* コンテキスト生成 */
    if (!ctx) {
        exit(EXIT_FAILURE);
    }

    input = flb_input(ctx, "lib", NULL); /* Input Plugin in_libを有効化 */
    flb_input_set(input, "tag", "test", NULL); /* Input Plugin の設定を行う。可変引数の最後には番兵としてNULLを与える */

    output = flb_output(ctx, "lib", my_stdout);/* Output Plugin out_libを有効化。out_libは第三引数としてコールバック関数を与えられる */
    flb_output_set(output, "match", "test", NULL);/* Output Plugin の設定を行う。可変引数の最後には番兵としてNULLを与える */

    /* Start the background worker */
    flb_start(ctx);/* サービス開始 */

    /* Push some data */
    for (i = 0; i < 100; i++) {
        n = snprintf(tmp, sizeof(tmp) - 1,
                     "[%lu, {\"key\": \"val %i\"}]",
                     time(NULL), i);
        flb_lib_push(input, tmp, n); /* データPush */
    }

    flb_stop(ctx); /* サービス停止 */

    /* Release Resources */
    flb_destroy(ctx);/* コンテキスト破棄 */

    return 0;
}

他にもexamplesにC APIを使ったサンプルが複数ありますので、確認してみて下さい。

github.com

ビルド方法(基本)

ビルドするにはCMakeが必要ですので、予めインストールしておきましょう。

ソース取得、cmake、makeという流れでビルドできます。

masterはビルドエラーになる場合があるので、バージョンタグから引っ張ってくるか、公式サイトからtarballを取得した方が良いでしょう。

$ git clone https://github.com/fluent/fluent-bit.git
$ cd build
$ cmake ..
$ make

ビルド方法(応用)

CMake時に-Dオプションを付けることで、Pluginをそぎ落としてサイズ縮小を図ったり、デバッグビルドを試したりすることができます。

Pluginを減らして、ファイルサイズを小さくする

FluentBitは組み込みを意識しているため、余剰なPluginを削減し、ファイルサイズを抑えたくなりがちです。 下記はInput Pluginの一つ、in_cpuを削減する例になります。

$ cmake .. -DFLB_IN_CPU=No
$ make

テストを実行する

FluentBitはGoogleTestを使い、UnitTestを行うことができます。

$ cmake -DFLB_TESTS=yes ..
$ make
$ make test

ロスコンパイルする

公式にはArmadillo向けのクロスコンパイル用の設定ファイルが含まれていますが、CMakeのお作法に則れば、他のプラットフォームに向けてもクロスコンパイル可能です。

以下は、RaspberryPi 2向けにクロスコンパイルする方法です。

下記をCrossCompile.cmakeというファイルに保存し、適宜CMAKE_FIND_ROOT_PATHのパスを変更しておきます。

set (CMAKE_SYSTEM_NAME Linux )

set (CMAKE_FIND_ROOT_PATH /PATH/TO/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian )

set (CMAKE_C_COMPILER   ${CMAKE_FIND_ROOT_PATH}/bin/arm-linux-gnueabihf-gcc )
set (CMAKE_CXX_COMPILER ${CMAKE_FIND_ROOT_PATH}/bin/arm-linux-gnueabihf-g++ )

set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

CMake実行時に、-DCMAKE_TOOLCHAIN_FILEとして上記ファイルパスを指定しましょう。

$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./CrossCompile.cmake  -DFLB_OUT_TD=No
$ make

成功すれば、下記のようにARM向けのバイナリができているはずです。

$ file bin/fluent-bit 
bin/fluent-bit: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, not stripped

リンク

*1:v0.8.5のリリースノートによると、500kレコード/秒を処理できるとのこと