こんにちは。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 を使えるように試行錯誤したのでした。
ログを集めた
何はなくともログです。ログ。
- cactiのweb管理画面で Settings > General > Poller Logging Level をDEVELにしてログ確認
- pollerの出力をファイルに出してチェック
すると、、、ログに下記の出力がありました。
CACTI2RRD: rrdtool update <filename> --template 99999:99999
ERROR: Not enough arguments
前者のほう、よくよく見るとrrdtoolのsyntaxが間違っている。よくよく見ると、本当は--template
の後は引数2つなんです。
rrdtoolのsyntax errorの結果、後者が出力されてました。 このせいでrrdファイルが更新されません。
回避策を探す
とりあえずエラーメッセージでググる。
Poller is missing template parameter according to cacti.log
すると、データ取得スクリプトの余計な空行を削除せよ、とのこと。
さっそくやってみると...効果なし。色々試しても効果なし。効果なし。なし。。
デバッグ
公式のデバッグマニュアルを見ながらデバッグ
manual:087:4help.2debugging - Cacti Docs
- Check Cacti Log File
- Check Basic Data Gathering
- Check Cacti's Poller
- Check MySQL Update
- 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)に改修されてました。
まとめ
オープンソースでよかった。