ゆるふわ技術日誌

エンジニア見習いの悪戦苦闘日記

Docker Compose + fluentdでNginxのログをmongoに流し込む

やりつくされてそうなネタですが、ちょっと研究の一環でログをうまいこと扱う必要が出てきたのでやってみました。

ひとまず実験として、Docker Composeを使って

  • Nginx
  • fluentd
  • MongoDB

を立ち上げて、Nginxのログをfluentdが拾って、MongoDBに流し込むということをやってみました。今回はログが複数のコンテナやノードに分散すると言ったことは考慮していません。

github.com

普通に、docker-compose upで上がります。

Nginxが8080で立ち上がるのでアクセスすると、数秒程度でMongoDBのadminデータベースのtestコレクションに書き込まれます。

8081番でWebGUIであるmongo-expressというのが上がっているのでアクセスすることで確認することができます。

f:id:uutarou:20181111223450p:plain

こんな感じ。ほぼ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_onlinkでmongoを指定してもDBが立ち上がるより前にMongoDBを見に行って勝手に落ちてくれちゃいます。

ポートが開くのを待ちたかったのでwait-for-itというシェルスクリプトをDockerイメージの中に仕込んでみた。

github.com

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だったわけだが、手こずるなら仮想マシンとか用意すればよかった気がした。

研究がやばい。