1クール続けるブログ

とりあえず1クール続けるソフトウェアエンジニアの備忘録

mtail事始め

記事一覧はこちら

mtail使っているけどちゃんと理解できていないかも…

という僕がmtailを改めて勉強したので書き留めておこうという記事です。
mtail自体は、apacheのログフォーマットをパースしてPrometheusで収集させるのに利用しているのですが、構築などは自分がプロジェクトにjoinしたときには既にあったため、なんとなくでも使えてはいました。
ですが不具合調査をすることになり、この機会に一から学んでみることにしました。

mtailについて

概要

github.com

mtailはアプリケーションのログからメトリクスを抽出してエクスポートしてくれるツール
メトリクスはPrometheusのようなPull型アーキテクチャを持つツールがスクレイプできるように、JSON形式もしくはPrometheus形式でHTTPサーバで公開できます。また、定期的にcollectdなどのツールに送ることも可能のようです。

入手方法

GitHubのリリースページから直接入手できます。2020年10月のリリースからは、armで動くバイナリも配布されています。
コンテナイメージですが、DockerHub上で公式イメージは手に入らないようです。GCRの公開リポジトリとかにありそうだなあと思ったんですがありませんでした。

実行方法

--progsでログをどうパースして、どのようにエクスポートするかを宣言したファイルのパスを指定する。一方で、--logsでは入力となるログファイルのパスを指定する。必須なのはこの2つ(のはず)。
--logtostderrはログをファイルではなく標準エラー出力に履く設定。基本的にmtailはサイドカーコンテナとして動かすケースがほとんどだと思うので、ログ出力は標準出力に履いてCloudWatch Logsなりでキャプチャ/転送してあげるのが易しいはず。
--progsではディレクトリを渡すこともできる。ファイルの名称は、末尾に.mtailがついていないと読み込んでくれない点について注意が必要です。

mtail --progs ./progs.mtail --logs /var/log/apache/access.log --logtostderr

メトリクスの公開先

デフォルトでポートは3903で公開されるので、それに合わせてPrometheusなりでサービスディスカバリしてあげるように設定して上げると良い。--port xxxxのようにコマンドの引数でポートはオーバーライド可能です。

mtailの設定DSL

exportする変数の定義がまず必要です。ここはPrometheusなどの収集ツール側から見れるメトリクス名になります。
counter, gauge, histogram が指定できます。

counter lines_total by path, method  # by を使うことでdimentionを追加できる
gauge queue_length

pattern(正規表現)を満たしたエントリに対してactionを行います
またpatternでキャプチャした変数はactionブロックで利用することが可能です

pattern {
   action
}

# 例: 1行ごとにカウントするシンプルなもの(行末ごとにactionが行われる)
/$/ {
   lines_total++
}

# + でpatternの結合、#より右はコメントなので無視する
/(?P<method>[A-Z]+) / + # %m - The request method.
/(?P<code>\d{3}) / + # %>s - Status code.
/(?P<sent_bytes>\d+) / + # %O - Bytes sent, including headers.
/$/ {
   http_response_size_bytes_total[$method][$code][$protocol] += $sent_bytes
}

mtailのテスト

mtailには構文のテスト方法と実際に得られる値までを計算して確認する方法があります。

  • 構文チェック
mtail --compile_only --progs ./progs
  • 実際にファイルを食わせて出力される値を確認
mtail --one_shot --progs ./progs.mtail --logs testdata/foo.log 
# jsonの出力が吐かれます

他にも色々機能がある…

中間値を保持する機能やHistogramをエクスポートする機能まではまだ追いきれていない状態ですが、なんとなく大枠はつかめたかと思います。
examplesが充実しているのはありがたいですね