この記事は、ケーシーエスキャロット Advent Calendar 2024の24日目の記事です。
初めに
以前の記事で、Prometheusについて(Prometheusを調べてみました)載せましたが、
前回は、パフォーマンス監視までの構築でしたので、
今回はRubyアプリが出力するログ(logger)の監視までの手順を書きたいと思います。
おさらい
前回の記事でも載せましたが、Prometheusでの監視全体図は以下になります。
今回は、ログ監視用のexporterとして、grok_exporterを利用します。
Prometheus/AlertManagerの基本的な構築方法や、exporterの簡単な紹介は、
以前の記事((Prometheusを調べてみました))を参考にしてください。
grok_exporterインストール
以下手順でgrok_exporterをインストールします。
% wget https://github.com/fstab/grok_exporter/releases/download/v1.0.0.RC5/grok_exporter-1.0.0.RC5.linux-amd64.zip
% unzip grok_exporter-1.0.0.RC5.linux-amd64.zip
% mv grok_exporter-1.0.0.RC3.linux-amd64 /etc/grok_exporter
% cd /etc/grok_exporter
ここまで進めて、/etc/grok_exporter配下に監視対象ファイルや監視メッセージについての情報を、ymlファイルに定義します。
今回の監視情報は、
- 管理対象のログファイル
/var/log/ruby_app.log - 管理対象エラーレベル
WARN/ERROR/FATAL
新たに作成するymlファイル(/etc/grok_exporter/ruby_log_config.yml)の内容は以下。
global:
config_version: 3
input:
type: file
paths:
- /var/log/ruby_app.log
readall: false
fail_on_missing_logfile: false
imports:
- type: grok_patterns
dir: /etc/grok_exporter/patterns
metrics:
- type: counter
name: error_count
help: Counter metric example with labels.
match: '%{RUBY_LOGGER}'
labels:
error_message: '{{.progname}} {{.loglevel}} {{.message}}'
logfile: '{{base .logfile}}'
retention: 1m
server:
protocol: http
port: 9145
ymlファイルの項目については、基本以下を参照。
今回githubで紹介されている例から、修正をした項目は以下になります。
input
- path
監視対象ファイルの/var/log/ruby_app.logを定義 - readall
設定値 | 内容 |
---|---|
true | 監視対象のファイルを先頭行から読み込む |
false | 監視対象のファイルを最終行(新規出力行)から読み込む |
- fail_on_missing_logfile
設定値 | 内容 |
---|---|
true | 監視対象ファイルが無い場合エラー |
false | 監視対象ファイルが無くても正常に起動 |
metrics
- name
metricsの名前 - match
取得したいログメッセージの正規表現を定義
今回定義している内容は 検知ログメッセージ定義以降で説明
labels
- error_message
フィールド名を定義できる為、今回、error_messageといフィールド名として、
プログラム名、ログレベル、メッセージをメトリクスから取得できるようにする
※'{{.progname}} {{.loglevel}} {{.message}}'の定義内容は以下の rubyファイル正規表現参照
server
- port
metric取得時に使用するTCPポート、今回は9145を利用
検知ログメッセージ定義
ymlのmetrics/matchでは、検知・取得したログメッセージを正規表現で定義します。
今回は、Rubyアプリが出力するログメッセージの検知となるので、
まずはメッセージのフォーマットを確認します。
Rubyアプリが出力するログフォーマット
Rubyアプリにてloggerを利用したログ出力のフォーマットは以下になります。
出力例:
I, [2024-12-19T12:30:45.129863 #8136] INFO -- : メッセージ
W, [2024-12-19T12:35:13.498129 #8137] WARN -- : 警告メッセージ
内容は以下の順で出力されています。
- ログレベル(略)
- ログ出力日付
- ログ出力をしたRubyアプリのプロセス番号
- ログレベル
- プログラム名
- ログメッセージ
正規表現
grok_exporterをインストールすると、patternsフォルダもダウンロードされ、
その中に正規表現が定義されている各種ファイルが存在します。
※ /etc/prometheus/patterns配下
-rw-r--r-- 1 root root 188 1月 13 2019 ruby
-rw-r--r-- 1 root root 104 1月 13 2019 redis
-rw-r--r-- 1 root root 845 1月 13 2019 rails
-rw-r--r-- 1 root root 142 1月 13 2019 postgresql
-rw-r--r-- 1 root root 9597 1月 13 2019 nagios
-rw-r--r-- 1 root root 614 1月 13 2019 mongodb
-rw-r--r-- 1 root root 190 1月 13 2019 mcollective-patterns
-rw-r--r-- 1 root root 49 1月 13 2019 mcollective
-rw-r--r-- 1 root root 1037 1月 13 2019 linux-syslog
-rw-r--r-- 1 root root 1087 1月 13 2019 junos
-rw-r--r-- 1 root root 1357 1月 13 2019 java
-rw-r--r-- 1 root root 3251 1月 13 2019 haproxy
-rw-r--r-- 1 root root 6199 1月 13 2019 grok-patterns
-rw-r--r-- 1 root root 9544 1月 13 2019 firewalls
-rw-r--r-- 1 root root 879 1月 13 2019 exim
-rw-r--r-- 1 root root 2154 1月 13 2019 bro
-rw-r--r-- 1 root root 4831 1月 13 2019 bacula
-rw-r--r-- 1 root root 1197 1月 13 2019 aws
今回はRubyアプリが対象となる為、ruby ファイルを利用します。
rubyファイルの内容は以下。
rubyファイル(正規表現)
RUBY_LOGLEVEL (?:DEBUG|FATAL|ERROR|WARN|INFO)
RUBY_LOGGER [DFEWI], \[%{TIMESTAMP_ISO8601:timestamp} #%{POSINT:pid}\] *%{RUBY_LOGLEVEL:loglevel} -- +%{DATA:progname}: %{GREEDYDATA:message}
定義されている RUBY_LOGGER をmatchに記載する事で、
メッセージの取得は出来るのですが、そのままですと、WARN/ERROR/FATAL以外の
DEBUG/INFOも検知してしまう為、RUBY_LOGLEVELの内容を変更してみます。
RUBY_LOGLEVEL (?:DEBUG|FATAL|ERROR|WARN|INFO)
↓
RUBY_LOGLEVEL (?:FATAL|ERROR|WARN)
ここまでの設定で、WARN/ERROR/FATALレベルのメッセージ検知が可能になりました。
grok_exporter起動
以下コマンドで実行します。
/etc/grok_exporter/grok_exporter -config /etc/grok_exporter/ruby_log_config.yml
次は、Prometheus/AlertManager本体の設定になります。
Prometheus
prometheus.yml
prometheus側のymlファイルにて、以下を追加。
scrape_configs:
- job_name: 'log_ruby'
static_configs:
- targets: ['client-host-name:9145']
client-host-nameはgrok exporterがインストールされているクライアント側のホスト名になります。
ポートは今回、ruby_log_config.ymlで定義している9145を指定。
alert_rules.yml
prometheus.yml側で読み込んでいるルール定義用のymlファイルに、以下を追加。
- name: log_alert
rules:
- alert: ruby
expr: error_count{job='log_ruby'} >= 1
labels:
severity: critical
group: "{{ $labels.error_message }}"
annotations:
summary: "[{{ $labels.job }}] error happened. [{{ $labels.instance }}]"
description: "{{ $labels.error_message }}"
「$labels.error_message」 についてですが、
こちらはgrok_exporter側のymlファイルで指定している、
以下の内容が反映されます。
labels:
error_message: '{{.progname}} {{.loglevel}} {{.message}}'
ここまで定義して、prometheusを再起動することで完了です!
次回は機会があれば、死活監視、プロセス監視も紹介出来ればと思います。