2015年5月27日水曜日

td-agent + Zabbix で Apache のレスポンスコードを監視する

概要

Apacheのログに出力されるレスポンスコードをZabbixで監視したいと思いました
Zabbixのログ監視 (log or logrt) でもいいかなと思ったのですがgrepルールを作成するのが面倒だったのでtd-agentを使って解決してみました

環境

  • CentOS 6.3 64bit
  • Zabbix Server 2.0.3
  • td-agent 0.12.7
  • fluent-plugin-zabbix 0.0.7
  • Apache Httpd 2.2.5

各種インストール

curl -L https://td-toolbelt.herokuapp.com/sh/install-redhat-td-agent2.sh | sh

上記のcurlコマンドでtd-agentをインストールした場合はyumコマンドでインストールしたことになっているので今後はrpmコマンドやyumコマンドから管理できるようになります

  • Apache Httpd
yum install httpd

全体的な流れ

簡単に今回紹介する作業の流れを記載します

  1. fluent-plugin-zabbix のインストール
  2. td-agent.conf の修正
  3. ACLの疎通確認
  4. Zabbix側にアイテムの登録
  5. 動作確認

という流れになります

fluent-plugin-zabbix のインストール

td-agentをインストールすると同時にtd-agent-gemというコマンドも利用できるようになります
これを使うとRubygemsで公開されているtd-agent用のプラグインを簡単に追加することができます

早速Zabbixと連携するためのプラグインをインストールします

td-agent-gem install fluent-plugin-zabbix fluent-plugin-datacounter

これでOKです
fluent-plugin-datacounterはZabbixにデータを送信する前に出現したステータスの回数をカウントするために使うので同時にインストールしておきます

td-agent.conf の修正

source

まずApacheのログファイルをtd-agentに入力させる設定を記載します

  • vim /etc/td-agent/td-agent.conf
<source>
  type tail
  format apache2
  path /var/log/httpd/access.log
  pos_file /var/log/td-agent/access.log.pos
  tag apache.log
</source>

今回はApacheのログはカスタマイズされていないデフォルトのログフォーマットを想定しています
もしログフォーマットが変更になっている場合はformatを独自のログパースフォーマットにしtime_formatを指定する必要があります
formatについてはこの記事の最後の方に作り方を紹介しているので参考にしてみてください

match

次に入力されたログからステータスコードの部分を取得しカウントする処理を記載します

  • vim /etc/td-agent/td-agent.conf
<match apache.log>
  type datacounter
  unit minute
  count_key code
  tag apache.status.count
  # patternX: X(1-9)
  pattern1 2xx ^2\d\d$
  pattern2 3xx ^3\d\d$
  pattern3 4xx ^4\d\d$
  pattern4 5xx ^5\d\d$
</match>

ここでfluent-plugin-datacounterを使います
Apacheのステータスコード+fluent-plugin-datacounterの組み合わせは定番と言っていいほど使われていると思います
Webでも検索すればサンプルはたくさん出てくると思います

unitパラメータで1分間で出現したステータスの量をカウントするようにしています
count_key<source>でパースしたログのステータスコードを表す部分のキーを設定してください
sourceでapache2を指定した場合はステータスコードの情報はcodeというキーに格納されるようです (参考)
ここも独自のフォーマットを作成した場合はそのフォーマットに合わせたキーを指定するようにしてください
patternXパラメータは1から指定していきます
ここで指定したパターンごとに値を集計してくれます

最後に集計したカウント結果をZabbixのアイテムとして登録する設定を記載します

<match apache.status.count>
  type zabbix
  zabbix_server zabbix_server
  host hostname
  name_key_pattern app.log_(unmatched|2xx|3xx|4xx|5xx)_count
</match>

zabbix_serverパラメータははZabbix ServerのIPアドレスまたはホスト名を入力します
hostパラメータは自信のホスト名を入力します

ポイントはname_key_patternパラメータです
この後、Zabbixにアイテムを登録するのですが、Zabbixのアイテムのキーと同じパターンにしなければいけない他、datacounterプラグインで出力されるJsonのキーとも一致している必要がありそうです
fluent-plugin-zabbixのソースコードを読んでいないので予測ですがname_key_patternで指定したキー情報を元にJsonから情報を取得し、取得した情報をZabbixの指定したキーと合致するアイテムに登録しているのだと思います

fileやstdoutで一度表示してみるとわかると思います
unmatchedというパターンもありますが、datacounterで指定したパターンに一致しない場合にここに格納されます

Tips

Zabbixに送信する前に値がちゃんと集計されているか確認したい場合は最後のmatchを書く前に以下を代わりに書いてテストするといいと思います

<match apache.status.count>
  type file
  path /var/log/td-agent/apache_status_count.log
</match>

集計結果をファイルに吐くようにしています
これでApacheにアクセスしてみて結果がファイルにちゃんと出力されることを確認してからZabbixに転送するmatchを書き始めてもいいと思います
ファイルに吐くのも面倒なのであればstdoutを使うのもいいと思います
注意するのはunitパラメータがminuteなのでログに出力されるのも1分毎になります

Zabbix側にアイテムの登録

Zabbixにアイテムを登録します
ここで作成するアイテムに対してtd-agentからアクセスが来てデータが格納されていきます
ここではテンプレートにアイテムを追加する手順をベースに紹介します

設定 -> テンプレート -> アイテムを追加したテンプレートのアイテム一覧を選択 -> アイテムの作成

でアイテム作成画面を表示し必要な情報を入力していきます

  • 名前 : apache.log_2xx_count (なんでもOKです、わかりやすい情報を入力しましょう)
  • タイプ : Zabbixトラッパー
  • キー : apache.log_2xx_count (td-agent.confのtype zabbixで入力した値と同じ値を設定する必要があります)

今回は単純にステータスの出現カウントをZabbixで管理したいと思います
キーにはname_key_patternで指定したパターンと同じキーを指定します
なので上記の要領で「apache.log_2xx_count」「apache.log_3xx_count」「apache.log_4xx_count」「apache.log_5xx_count」「apache.log_unmatched_count」と5つ分のアイテムを登録してください

カウント以外にも「rate」と「percentage」という項目もtd-agent側は送ってくれているので「apache.log_2xx_rate」「apache.log_2xx_percentage」 … みたいなアイテムを追加すればそこにも値が入るようになります
rate と percentage は型を浮動小数点型にするといいです

ACLの疎通確認

今回Zabbixトラッパーを使うため

App in td-agent -> tcp/10051 -> Zabbix Server

の疎通が必要になります
通常のZabbix監視ではServerから監視対象のAppへの10050が通っていればアイテムを取得できますが今回は逆方向の通信が必要になります

動作確認

Zabbix Server, td-agent, Apache を起動してアクセスしてみて最終的にZabbix Serverにデータが登録されていればOKです
確認は最新データあたりから実施するといいと思います

問題になりそうなのはtd-agent.confの設定だと思います

  • <source>で指定したログがちゃんと存在するか、アクセス権限はあるか
  • <source>で指定したformatでちゃんとログがパースできているか
  • <match>のdatacounterの定義の部分でカウントするべきcount_keyが間違っていないか
  • <match>のdatacounterの定義の部分でpatternXがちゃんと設定されているか
  • <match>のdatacounterのあとでちゃんとデータが取得できているのか
  • <match>のzabbixの定義で疎通はちゃんとできているか
  • <match>のzabbixの定義でname_key_patternに指定しているパターンはdatacounterの出力パターンと一致しているか
  • <match>のzabbixの定義でname_key_patternに指定しているパターンはZabbixに登録したアイテムのパターンと一致しているか

などなど結構ハマリポイントはあると思います
また後述のTipsに記載しているのもハマリポイントだと思います(自分はハマリました)
対応方法としては1つ1つsourceやmatchを検証するのがいいと思います
いきなり全部を連結しようとするとうまく行かないので、まずはstdoutで出力してちゃんとデータが取れているか確認するといいと思います
あとは、td-agent.conf のログを詳細に出すようにして確認しながら解決していく感じでしょうか

Tips

当たり前なのかもしれないですが念のためメモしておきます
matchに該当する定義が複数ある場合はtd-agent.confの先に書かれているほうが優先されるようです

例えば

<source>
  type tail
  path /path/to/log
  tag access.log
  ...
</source>

<match access.*>
  type zabbix
  ...
</match>

<match access.log>
  type file
  ...
</match>

としている場合には先に書かれているmatchが優先されるためあとに書かれたfileのmatchは実行されません

P.S 20150527
type copyを使うと解決できます
http://papix.hatenablog.com/entry/2014/11/05/185449

最後に

どれもこれもOSSを使っているのでバージョンが上がれば手順は変わると思いますのでご注意ください

最終的に可視化されるようになると運用では便利なのでぜひ頑張って構築してみてください

参考サイト

0 件のコメント:

コメントを投稿