🐬

AWS firelens 小ネタ2 環境変数はバンバン使っていこう、Yamlでも使えるよ。

2024/09/25に公開

環境変数をconf内部で使用できるので使っていきましょう編

プロジェクト、環境ごとに振り分け先って変わりますよね?
その変更毎にfirelensのImageを作る必要はなく、こんな感じで記述できます。

[Service]
    Flush 1
    Grace 30
    Log_Level ${LOG_LEVEL}

[OUTPUT]
    Name cloudwatch_logs
    Match *-firelens-*
    region ap-northeast-1
    log_stream_prefix other_
    log_group_name ${OTHER_LOG_CW_GROPU_NAME}

[OUTPUT]
    Name kinesis_firehose
    Match access
    region ap-northeast-1
    delivery_stream ${PROJECT_NAME}-${ENV}-accesslog-stream

こんな感じで使えます。便利ですよね。

環境変数はtask_defのfirelensの所で設定です。間違えないように。
イメージのレポジトリ設定とかはサンプルなので気を付けてください。

        {
            "name": "log_router",
            "image": "123456789.dkr.ecr.ap-northeast-1.amazonaws.com/fluentbit-test:latest",
            "essential": true,
            "environment": [
                {
                    "name": "LOG_LEVEL",
                    "value": "info"
                },
                {
                    "name": "OTHER_LOG_CW_GROPU_NAME",
                    "value": "/ecs/fluentbit-test"
                },
                {
                    "name": "PROJECT_NAME",
                    "value": "dongebabi"
                },
                {
                    "name": "ENV",
                    "value": "dev"
                }
            ],
         }

ただし、デフォルト値は使えません。残念ながら。。。
LOG_LEVELとかはデフォルト値使いたいですよね。改良して欲しいところですね。

注意 Yaml形式(クラッシックじゃない方)でも環境変数使えます。けど。。

filelensってfluentbitのベースが1.9.10なんですよ。(2024/09)
https://github.com/aws/aws-for-fluent-bit/blob/mainline/scripts/dockerfiles/Dockerfile.build

https://gallery.ecr.aws/aws-observability/aws-for-fluent-bit

更新されてないんですよねぇ。。本家が3系にバージョンアップしちゃっているのでちょっと心配です。
https://docs.fluentbit.io/manual

はい、で、yaml形式は1.9では実験的で、2.0から正式対応と書かれております。
https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/yaml

なので1.9.10を使っているaws-for-fluent-bitのイメージで使うのはあまりお勧めしません。

でもどーしても使いたいという場合は、例えばこのようにdockerfileを書けば使えます

dockerfile

FROM amazon/aws-for-fluent-bit:debug-latest

COPY ./fluentd.yaml /fluent-bit/etc/fluent-bit_custom.yaml
COPY ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

entrypoint.sh

echo -n "AWS for Fluent Bit Container Image Version "
cat /AWS_FOR_FLUENT_BIT_VERSION
exec /fluent-bit/bin/fluent-bit -e /fluent-bit/firehose.so -e /fluent-bit/cloudwatch.so -e /fluent-bit/kinesis.so -c /fluent-bit/etc/fluent-bit_custom.yaml

元ファイルは
https://github.com/aws/aws-for-fluent-bit/blob/mainline/entrypoint.sh
これで、ベースにしているaws-for-fluent-bitのImageの、エントリーポイントに指定されていますのでこちらのファイルを書き換えるのが早いかな。と言ったところです。
(エントリーポイントを無効にして、コマンドでyaml指定でもOKです)

yaml形式で環境変数

yaml形式で環境変数が使えないと思われちゃう最大の理由がenvの項目が有ることだと思うんですよね
https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/yaml/configuration-file

# setting up a local environment variable
env:
    flush_interval: 1

# service configuration
service:
    flush:       ${flush_interval}
    log_level:   info
    http_server: on

この項目があるので、外からは設定できないんじゃない?
また、外から設定したら上書きできるんじゃない?
と思わせてしまいます。

結論は
env項目で指定した変数名は上書きできません。
別名なら問題なく動作します。

簡単なサンプルを用意しましょう(ローカル環境で検証用)
dockerファイルは上記と同様のものを使用

fluentd.yaml

env:
  interval: 1
service:
    flush:       ${interval}
    log_level:   ${LOG_LEVEL}

input:
  name: dummy
  dummy: '{"message": "yaml env test!" ,"log_level": "${LOG_LEVEL}", "flush": "${interval}"}'

output:
  name: stdout
  match: *

ビルドコマンドと実行コマンド

docker build -t aws-fluentbit:latest .
docker run --env LOG_LEVEL=debug aws-fluentbit:latest

こんな形で環境変数がそれぞれ設定で正しく認識されているのが分かります。

Fluent Bit v1.9.10
* Copyright (C) 2015-2022 The Fluent Bit Authors
* Fluent Bit is a CNCF sub-project under the umbrella of Fluentd
* https://fluentbit.io

[2024/09/25 12:36:38] [ info] Configuration:
[2024/09/25 12:36:38] [ info]  flush time     | 1.000000 seconds
[2024/09/25 12:36:38] [ info]  grace          | 5 seconds
[2024/09/25 12:36:38] [ info]  daemon         | 0
[2024/09/25 12:36:38] [ info] ___________
[2024/09/25 12:36:38] [ info]  inputs:
[2024/09/25 12:36:38] [ info]      dummy
[2024/09/25 12:36:38] [ info] ___________
[2024/09/25 12:36:38] [ info]  filters:
[2024/09/25 12:36:38] [ info] ___________
[2024/09/25 12:36:38] [ info]  outputs:
[2024/09/25 12:36:38] [ info]      stdout.0
[2024/09/25 12:36:38] [ info] ___________
[2024/09/25 12:36:38] [ info]  collectors:
[2024/09/25 12:36:38] [ info] [fluent bit] version=1.9.10, commit=f1e808647d, pid=1
[2024/09/25 12:36:38] [debug] [engine] coroutine stack size: 196608 bytes (192.0K)
[2024/09/25 12:36:38] [ info] [storage] version=1.4.0, type=memory-only, sync=normal, checksum=disabled, max_chunks_up=128
[2024/09/25 12:36:38] [ info] [cmetrics] version=0.3.7
[2024/09/25 12:36:38] [debug] [dummy:dummy.0] created event channels: read=27 write=28
[2024/09/25 12:36:38] [debug] [stdout:stdout.0] created event channels: read=29 write=30
[2024/09/25 12:36:38] [debug] [router] match rule dummy.0:stdout.0
[2024/09/25 12:36:38] [ info] [sp] stream processor started
[2024/09/25 12:36:38] [ info] [output:stdout:stdout.0] worker #0 started
[2024/09/25 12:36:38] [debug] [input chunk] update output instances with new chunk size diff=66, records=1, input=dummy.0
[0] dummy.0: [1727267798.722323875, {"message"=>"This is a dummy log", "environment"=>"debug", "flush"=>"1"}]
[2024/09/25 12:36:39] [debug] [task] created task=0xffff2d244460 id=0 OK
[2024/09/25 12:36:39] [debug] [output:stdout:stdout.0] task_id=0 assigned to thread #0
[2024/09/25 12:36:39] [debug] [input chunk] update output instances with new chunk size diff=66, records=1, input=dummy.0
[2024/09/25 12:36:39] [debug] [out flush] cb_destroy coro_id=0
[2024/09/25 12:36:39] [debug] [task] destroy task=0xffff2d244460 (task_id=0)
[0] dummy.0: [1727267799.725737292, {"message"=>"This is a dummy log", "environment"=>"debug", "flush"=>"1"}]

本家でこのyamlはエラーで使えない

現時点での最新、fluentbit3.1.8(2024/09)ではこのyamlは使えません。。。怖いですねぇ。。。
なので、もしfirelensのバージョンが上がった時に影響が出る可能性が有るのでyaml形式はお勧めできません。

fluentbit3.1 系では

env:
  interval: 1
service:
    flush:       ${interval}
    log_level:   ${LOG_LEVEL}

pipeline:
  inputs:
    - name: dummy
      dummy: '{"message": "yaml env test!" ,"log_level": "${LOG_LEVEL}", "flush": "${interval}"}'

  outputs:
    - name: stdout
      match: *

となります。

で、環境変数の上書きとかは出来るようになっているかなーと思ってやってみますが。。。
なってません。。。
今後に期待しましょう。

Discussion