概要
docker の fluentd ドライバで stdout と stderr を別々のタグで扱う方法を紹介します
実際に stdout と stderr に出力するアプリを作成し試しています
環境
- macOS 10.14.5
- docker 18.09.2
- fluentd 1.3.2
- rewrite-tag-filter 2.2.0
stdout と stderr にそれぞれ出力するアプリの作成
Sinatra で作成します
ここはそれぞれに出力できるのであれば何でも OK です
bundle init
vim Gemfile
gem "sinatra"
bundle install --path vendor
vim app.rb
require 'sinatra/base'
require 'logger'
class MyApp < Sinatra::Base
configure do
unless ENV['LOCAL'] == "true"
$stdout = IO.new(IO.sysopen("/proc/1/fd/1", "w"), "w")
$stdout.sync = true
STDOUT = $stdout
end
set :ologger, Logger.new(STDOUT)
set :elogger, Logger.new(STDERR)
end
get '/stdout' do
settings.ologger.info("stdout")
'stdout'
end
get '/stderr' do
settings.elogger.info("stderr")
'stderr'
end
end
vim config.ru
require './app.rb'
run MyApp
こんな感じです
Ruby アプリの場合 stdout は少し工夫が必要なのでそれを入れています
動作確認としては stdout と stderr だけに表示するように実行してみましょう
LOCAL=true bundle exec rackup config.ru 2> /dev/null
LOCAL=true bundle exec rackup config.ru > /dev/null
上が stdout のみで下が stderr のみ表示する実行方法です
Dockerfile
次に作成したアプリを docker 上で動作するようにします
vim Dockerfile
FROM ruby
ADD . /home
WORKDIR /home
RUN gem install bundler
RUN bundle install --path vendor
EXPOSE 9292
CMD ["bundle", "exec", "rackup", "config.ru", "-o", "0.0.0.0"]
docker build -t myapp .
これでイメージを作成します
fluentd コンテナの作成
まずは fluentd コンテナから立ち上げます
今回の目的は作成した Sinatra アプリの stdout と stderr を fluentd で別々に扱うことです
なので fluent.conf
をそのように記載する必要があります
ポイントは rewrite_tag_filter を使って stdout と stdout に対して別々のタグを付与する必要がある点です
mkdir fluentd
cd fluentd
vim fluent.conf
<source>
@type forward
</source>
<match docker.myapp>
@type rewrite_tag_filter
<rule>
key source
pattern /^stdout$/
tag out.${tag}
</rule>
<rule>
key source
pattern /^stderr$/
tag err.${tag}
</rule>
</match>
<match out.docker.myapp>
@type stdout
</match>
<filter err.docker.myapp>
@type record_transformer
<record>
hostname "#{Socket.gethostname}"
</record>
</filter>
<match err.docker.myapp>
@type stdout
</match>
record-transformer はテスト用に使っています
stderr にだけフィールドを追加して出力しています
デフォルトの fluetd イメージには rewrite-tag-filter プラグインが含まれてないのでプラグインをインストールしたイメージを作成します
vim Dockerfile
FROM fluent/fluentd
RUN apk add --update --virtual .build-deps \
sudo build-base ruby-dev \
&& sudo gem install \
fluent-plugin-rewrite-tag-filter \
&& sudo gem sources --clear-all \
&& apk del .build-deps \
&& rm -rf /var/cache/apk/* \
/home/fluent/.gem/ruby/2.4.0/cache/*.gem
docker build -t myfluentd .
これで fluentd コンテナを起動しましょう
docker run -d -p 24224:24224 -p 24224:24224/udp -v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf -e FLUENTD_CONF=fluent.conf --name=fluentd myfluentd
docker logs -f fluentd
アプリコンテナの起動
ではアプリコンテナを起動しましょう
コンテナを起動する際にロギングドライバに fluentd を指定しましょう
またタグは docker.myapp
にします
docker run -d --log-driver=fluentd --log-opt fluentd-address=192.168.128.100:24224 --log-opt tag="docker.myapp" -p 9292:9292 myapp
動作確認
fluentd コンテナのログを見ておきましょう
そしてアプリの stdout, stderr にアクセスしましょう
curl localhost:9292/stdout
curl localhost:9292/stderr
すると以下のように source -> stderr なログにだけ hostname というフィールドが追加されていることがわかると思います
最後に
ポイントは rewrite-tag-filter を使って stdout と stderr を一旦受け取った上で再度タグ付けをする点でした
今回は 1 つのコンテナのログのみ対応しましたが他にも stdout と stderr を別々に扱いたい場合は docker.myapp
のように別のタグの match を定義すれば OK です
0 件のコメント:
コメントを投稿