PrometheusとmtailのNG例

PrometheusとmtailのNG例

Prometheusとmtail-exporterでログ監視をやるときのダメな例

最初に書いておきますが、以下は動かない例です。

要点

  • Prometheusのメトリクスは数値のみで文字列は不可
  • 文字列はラベルに設定できるが、多様な文字列をラベルに設定するのは、時系列DBには適さない
  • ラベルを設定した連想配列のメトリクスは初期化されないため、rate() や delta() などで最初の変化を検出できない

やりたかったこと

  • ログに特定の文字列("error"とか)が出現したらアラートを出す → これは普通にできる
  • そのログの内容もアラートに出したいな → これはできない

やったこと

mtailの設定

counter log_error_count
counter log_error by log_file, log_line limit 1

/(.*)((?i)error)(.*)/ {
  log_error_count++
  log_error[getfilename()][$1 + $2 + $3]++
  del log_error[getfilename()][$1 + $2 + $3] after 1h
}

Prometheusのルール設定

  • 単純なカウンター、連想配列のカウンター、どちらかが増加したらアラートのつもり
  - alert: ErrorLog1
    expr: rate(log_error_count[1m]) != 0
    for: 0s
    labels:
      severity: error
    annotations:
      summary: "Instance {{ $labels.instance }} error log"
      description: "{{ $labels.instance }} of job {{ $labels.job }} error log found."

  - alert: ErrorLog2
    expr: rate(log_error[1m]) != 0
    for: 0s
    labels:
      severity: error
    annotations:
      summary: "Instance {{ $labels.instance }} error log"
      description: "{{ $labels.instance }} of job {{ $labels.job }} error log found."

うまくいかないこと

  • 単純なカウンターはいいけど、連想配列の方はrate() や delta() がうまく動作しない
    • メトリクスが未定義の状態から "1" になっても値の変化が認識されないようだ
    • まったく同じログ(上記の例では、同じログファイル名に、全く同じログの文字列)が出れば、"1" → "2" にカウントアップされるから、それは認識される
    • でもログの文字列にはタイムスタンプが付いていることが多いから、まったく同じ文字列の行のログが複数というのはまぁない

ということで、以上の試みはお蔵入り

参考

  • Is there any plan for prometheus to support string type metrics? · Issue #2227 · prometheus/prometheus · GitHub
    https://github.com/prometheus/prometheus/issues/2227
    • Prometheusのメトリクスは数値だけです。だって文字列はメトリクスじゃないから。ラベルに色々な任意の文字列を入れるのも良くないです。ELKでも使えば?