Docker Compose + fluentdでNginxのログをmongoに流し込む
やりつくされてそうなネタですが、ちょっと研究の一環でログをうまいこと扱う必要が出てきたのでやってみました。
ひとまず実験として、Docker Composeを使って
- Nginx
- fluentd
- MongoDB
を立ち上げて、Nginxのログをfluentdが拾って、MongoDBに流し込むということをやってみました。今回はログが複数のコンテナやノードに分散すると言ったことは考慮していません。
普通に、docker-compose up
で上がります。
Nginxが8080で立ち上がるのでアクセスすると、数秒程度でMongoDBのadminデータベースのtestコレクションに書き込まれます。
8081番でWebGUIであるmongo-expressというのが上がっているのでアクセスすることで確認することができます。
こんな感じ。ほぼPluginの説明から拾ってきてコピペしたものだが、fluentdのconfigはこんな感じ。
<source> @type tail path /var/log/nginx/access.log # pos_file /var/log/td-agent/tmp/access.log.pos tag nginx.access format ltsv </source> <match nginx.**> @type mongo host mongo port 27017 database admin collection test # for capped collection capped capped_size 1024m # authentication user root password example # key name of timestamp time_key time # flush flush_interval 10s </match>
sourceはtailというものを使うとpathで指定したファイルの末尾を監視(名前の通りtail -f
と同じ)してくれます。
それをformatで指定したフォーマットを使って取り込んでくれるという認識。ltsvはタブで各項目を区切るフォーマットらしく、fluentdではよく使われてる気がした。初期設定のフォーマットだと、入ってくる文字によってはparseに失敗することがあるらしい。
そして、matchではmongoを指定しています。mongoに関してはDockerイメージには含まれていないので、自分でイメージをビルドする必要があります。
後の設定はまぁ見ればわかるでしょうという感じ。
ところで、今回DBの中身を見るために使用したmongo-expressですが、MongoDB側のポートが開くまで待ってくれるという処理がなさそうなので、depends_on
やlink
でmongoを指定してもDBが立ち上がるより前にMongoDBを見に行って勝手に落ちてくれちゃいます。
ポートが開くのを待ちたかったのでwait-for-itというシェルスクリプトをDockerイメージの中に仕込んでみた。
Dockerイメージは以下のような感じ。
FROM mongo-express RUN wget https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh RUN chmod a+x wait-for-it.sh CMD ./wait-for-it.sh mongo:27017 -- tini -- /docker-entrypoint.sh
これで解決した。
雑談
久々に真面目な技術記事を書いた。サクッと行けたかのように涼しげな顔で書いているがここまでうまく動かすのに結構な時間を使ってしまったのはちょっと反省。
Dockerで動かす必要があったのかと言われればそうではなく、手軽さを求めてのDockerだったわけだが、手こずるなら仮想マシンとか用意すればよかった気がした。
研究がやばい。