qpstudy 1周年記念LT大会!でLTした『Zabbixで人間監視』、けっこう反響があったので実装についてさらしてみます。
ビューとしてはLTで見せたように、2つのスクリーンを作っています。
全体監視画面
デモ画面
何人かのアイコンを並べたマップとイベント履歴を表示しています。(マップのリンクは自分に対するリプライ頻度をあらわします。)
アイコンの追加は「管理」→「一般設定」→「イメージ」で。
個人監視画面
デモ画面
タイムラインのテキストといくつかのグラフ(時間あたりのツイート数と、フォロワー数、リスト数の推移)を表示しています。
人間相手ではZabbixエージェントもSNMPも使えないので、監視は全て外部監視かZabbixトラッパーで行います。
これらはいくつかのスクリプトで成り立ってます。
[zabbix@admin01 ~]$ ls -1 /etc/zabbix/externalscripts/ config get_tw_replies.pl twitter.reply.count twitter.timeline.get twitter.userinfo.get [zabbix@admin01 ~]$ cat /etc/zabbix/externalscripts/config/twitter_config.yaml access_token: access_token: 0000000-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX access_token_secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX consumer_token: consumer_key: XXXXXXXXXXXXXXXXXXXX consumer_secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX profile_dir: /var/data/twitter/profile reply_dir: /var/data/twitter/reply timeline_dir: /var/data/twitter/timeline
ユーザ情報、タイムライン取得部分について簡単に説明してみましょう。
ユーザ情報取得
以下の監視アイテムから成り立ってます。
ユーザ情報取得スクリプトをキックする外部監視アイテム
{HOSTNAME1}マクロを使ってスクリプトにホスト名で指定したTwitterIDを渡しています。
(DNS名をTwitterIDにして「DNS名で監視」を選択すれば第一引数でそれが渡ってきますが、ちょっと気持ち悪いのでこの方法)
そのスクリプトからzabbix_senderで情報を突っ込むための複数のZabbixトラッパーアイテム
Zabbixトラッパーを使っているのツイート数、フォロワー数等を1度で取得、Zabbixに送信してTwitterAPI呼び出し回数を減らすためで、
これをcronスクリプトではなく外部監視アイテムでキックしているのは、監視対象、監視間隔をZabbixサーバ上で一元管理するためです。
スクリプト(twitter.userinfo.get)の中身は以下のようになっています。
#!/usr/bin/perl use strict; use warnings; use utf8; use Net::Twitter::Lite; use YAML; use Data::Dumper; use File::Basename; my @items = qw/friends_count followers_count statuses_count favourites_count listed_count/; my $twitter_config_file = dirname($0)."/config/twitter_config.yaml"; my $zabbix_sender = "/usr/bin/zabbix_sender -z 127.0.0.1 >/dev/null "; my $screen_name = $ARGV[1]; my $twitter_config = YAML::LoadFile $twitter_config_file; my $consumer_token = $twitter_config->{consumer_token}; my $access_token = $twitter_config->{access_token}; ### get user information my $t = Net::Twitter::Lite->new(%$consumer_token); $t->access_token($access_token->{access_token}); $t->access_token_secret($access_token->{access_token_secret}); my $profile = $t->show_user($screen_name); unless($profile){ print 255; exit; } ### send data for my $item (@items){ system "$zabbix_sender -s $screen_name -k twitter.userinfo.$item -o ".$profile->{$item}; } print 0; exit;
タイムライン取得
これもユーザ情報取得と同じように2段構えになっています。
そのスクリプトからzabbix_senderで情報を突っ込むためのZabbixトラッパーアイテム
zabbix_senderは--with-timestampsオプションを用いるとタイムスタンプ付きで監視データを送信できるので、--input-fileオプションと合わせてツイートテキストを一気に突っ込んでいます。
詳しくはzabbix_senderで過去のグラフを作る - IT 東京 楽しいと思うことを参照してください。
スクリプト(twitter.timeline.get)の中身はこんな感じです
#!/usr/bin/perl use strict; use warnings; use utf8; use Net::Twitter::Lite; use YAML; use Data::Dumper; use File::Basename; my $twitter_config_file = dirname($0)."/config/twitter_config.yaml"; my $zabbix_sender = "/usr/bin/zabbix_sender -z 127.0.0.1 --input-file - --with-timestamps > /dev/null"; my $screen_name = $ARGV[1]; my $twitter_config = YAML::LoadFile $twitter_config_file; my $consumer_token = $twitter_config->{consumer_token}; my $access_token = $twitter_config->{access_token}; my $timeline_dir = $twitter_config->{timeline_dir}; my $since_id_file = "$timeline_dir/$screen_name.since_id"; my $since_id = load_since_id(); ### get tweets my $t = Net::Twitter::Lite->new(%$consumer_token); $t->access_token($access_token->{access_token}); $t->access_token_secret($access_token->{access_token_secret}); my %opts = (screen_name => $screen_name); $opts{since_id} = $since_id if $since_id; my $tweets = $t->user_timeline(\%opts); unless(@$tweets){ print 0; exit; } ### send data open my $fh, '|-', $zabbix_sender; binmode($fh, ":utf8"); for my $tweet (reverse @$tweets){ print $fh "$screen_name twitter.timeline ". get_unixtime($tweet->{created_at}) ." ". $tweet->{text} ."\n"; # debug_print("$screen_name twitter.timeline ". get_unixtime($tweet->{created_at}) ." ". $tweet->{text} ."\n"); } close $fh; save_since_id($tweets->[0]->{id}); print scalar @$tweets; exit; ### end of main ### sub debug_print { my $msg = shift; chomp $msg; open my $fh, ">>", "/tmp/zabbix_error_log"; print $fh localtime(time) . " $msg\n"; close $fh; } sub save_since_id { my $since_id = shift; open my $fh, ">", $since_id_file; print $fh $since_id; close $fh; } sub load_since_id { open my $fh, "<", $since_id_file; my $since_id = <$fh>; close $fh; return $since_id; } sub get_unixtime { my $created_at = shift; if (defined $created_at) { $created_at =~ s/\+0000/UTC/; $created_at = HTTP::Date::str2time($created_at); } else { $created_at = undef; } return $created_at; }
とりあえずここまで!!!
気が向いたら、フォローすると監視登録され、アラートをタイムラインに流すTwitterボットを作ろうかと思います。
あとは特定キーワード(#qpstudyや「ほむほむ」)のツイート速度監視とか、かなぁ。
見た目のインパクトとしてやはりマップはおもしろいので、それももっとうまく使いたいところ。(しかしマップ関連のZabbixAPI、挙動がよくわからん・・・)