こんにちは。CTOの馬場です。
だいぶご無沙汰ですが、今回もインフラエンジニア向けにちょっとした情報を紹介します。
今回はcacti 0.8.7hでハマったので、その顛末と回避方法を書いておきます。
ハマった事象は **「データ取得は正常だけどrrdファイルが更新されない」** でした。。。
# 環境
– CentOS 5.6
– apache 2.2.21 (ソースインストール)
– php 5.3.8 (ソースインストール)
– MySQL 5.5.15 (本家謹製rpm)
– cacti 0.8.7h + spine
イケてるtemplateが使いたかったので、[better-cacti-templates](http://groups.google.com/group/better-cacti-templates) を使えるように試行錯誤したのでした。
# ログを集めた
何はなくともログです。ログ。
– cactiのweb管理画面で Settings > General > Poller Logging Level をDEVELにしてログ確認
– pollerの出力をファイルに出してチェック
すると、、、ログに下記の出力がありました。
– `CACTI2RRD: rrdtool update
– `ERROR: Not enough arguments`
前者のほう、よくよく見るとrrdtoolのsyntaxが間違っている。よくよく見ると、本当は`–template`の後は引数2つなんです。
rrdtoolのsyntax errorの結果、後者が出力されてました。
このせいでrrdファイルが更新されません。
# 回避策を探す
とりあえずエラーメッセージでググる。
[Poller is missing template parameter according to cacti.log](http://forums.cacti.net/viewtopic.php?f=2&t=41673)
すると、データ取得スクリプトの余計な空行を削除せよ、とのこと。
さっそくやってみると…効果なし。色々試しても効果なし。効果なし。なし。。
# デバッグ
公式のデバッグマニュアルを見ながらデバッグ
[manual:087:4_help.2_debugging – Cacti Docs](http://docs.cacti.net/manual:087:4_help.2_debugging)
1. Check Cacti Log File
2. Check Basic Data Gathering
3. Check Cacti’s Poller
4. Check MySQL Update
5. Check RRD File Update
今までの調査で 5. はダメなのがわかっていて、
3. はokなのがわかっているので、
4. を実施。
## Check MySQL Update
mysqlの設定を変更して全クエリを出力したのでした。
設定したら、 `show variables` して結果の確認を忘れずに!
– `set global log_slow_queries=On`
– `set global long_query_time=0;`
この状態でpollingが走ると、mysqlに対して実行された全クエリがスローログに出力されます。かなり大量なのでびっくりしてください。
実行されたクエリが取得できたら、データソースのIDを頼りに、 `poller_output` テーブルにデータを投入している箇所を探します。
INSERT INTO poller_output (local_data_id, rrd_name, time, output) VALUES ( データ ), ( データ ), ( データ ), ( データ ), ( データ ), ( データ ), ( データ ) ON DUPLICATE KEY UPDATE output=VALUES(output);
このクエリを手動でも実行してみて、データが正常に投入できているかどうか、取得できるかを確認します。
…今回はここは正常でした。明らかにオカシイ。まぁもともとオカシイから調べてるんですが。。。
## ソース読み
公式マニュアルのお陰でMySQLが原因ではないことがわかったので、ハラを決めてソースを読みます。
今回はログに `CACTI2RRD: rrdtool update 〜` と記載があり、ここがおかしいことはわかっていたので、この `CACTI2RRD` ととっかかりに調査します。
# find /var/www/cacti/ -type f -name "*.php"|xargs grep -nHi "CACTI2RRD"
/var/www/cacti/lib/rrd.php:80: cacti_log("CACTI2RRD: " . read_config_option("path_rrdtool") . " $command_line", $log_to_stdout, $logopt);
/var/www/cacti/lib/rrd.php:399: cacti_log("CACTI2RRD: " . read_config_option("path_rrdtool") . " tune $data_source_path $rrd_tune");
2箇所しかない!ということで、rrd.phpを見てみます。
– `rrdtool_execute` 関数の中で呼ばれているのがクサい
– → `rrdtool_execute` と `update` の組み合わせで呼ばれている行を探す
– → `rrdtool_function_update` がクサい
– → 呼んでいる箇所を探す。同じファイルにはないのでfindとxargsを組み合わせて探す
– → `/var/www/cacti/lib/poller.php` でしか呼んでない
– → `/var/www/cacti/lib/poller.php` を該当箇所からさかのぼって読む。読む。
– → 実行されているはずのSQLが実行されていない!
– → 分岐がおかしい!
– → `is_hexadecimal`関数の結果がおかしい!
– → 定義されている箇所が見当たらないのでfindとxargsを組み合わせて探す
– → `lib/functions.php`にあった!
と、いうわけで、 `lib/functions.php` の `is_hexadecimal` 関数を修正して対応完了。
コーディングミスで複数値対応ができなくなっていたようです。
(推測ですがipv6対応したかったもよう)
# SVNみてみる
最新版(0.8.7のHEAD)では直ってる…
rev 6251→6252(2011/1/29)でエンバグして、rev 6850→6851(2011/10/9)に改修されてました。
# まとめ
オープンソースでよかった。