【Hinemos,Perl】ツイートをシステムログ監視で検知する
投稿日: / 更新日:
この記事は2年以上前に書かれたものです。情報が古い可能性があります。
Twitterは、ご存じのとおり様々な情報をほぼリアルタイムに入手することができる、非常に便利なサービスですが、実際には、定期的にTwitterクライアント等を開いて、その時点までに取得したツイートを後追いで確認するのが通常の使い方ではないかと思います。従って、(自分にとって)特に重要な情報を1秒でも早く確認したい、というような場合、Twitterクライアントと1日中にらめっこしなければなりませんが、これはさすがに現実的ではないため、Hinemosと簡単なPerlプログラムを使用して、できるだけリアルタイムに、かつラクに実現する方法を検討してみます。
TwitterのStreaming APIを使用すると、レートリミット(単位時間あたりのAPI呼び出し回数制限)を回避してツイート等の情報を取得することができます。今回は、このAPIを使用してツイートを取得し、ローカルホスト上のsyslogデーモンへ都度転送するPerlプログラムを作成してみます。例によって、CPANモジュールをフル活用し、できるだけ短いプログラムを実装します。サンプルコードは以下のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
#!/usr/bin/env perl use strict; use warnings; use Encode; use Sys::Syslog; use YAML::XS 'Load'; use List::MoreUtils 'none'; use File::Basename 'basename'; use AnyEvent::Twitter::Stream; use Net::Twitter::Lite::WithAPIv1_1; my $conf = Load(do{ local $/; <DATA> }); my %creds = %{$conf->{creds}}; my @target_users = @{$conf->{target_users}}; my $api = Net::Twitter::Lite::WithAPIv1_1->new(%creds); my $user_id_of = {}; for my $user (@{ $api->friends->{users} }) { $user_id_of->{ $user->{screen_name} } = $user->{id}; } openlog(basename($0), 'ndelay,pid', 'user'); my $done = AE::cv; my $streamer = AnyEvent::Twitter::Stream->new( %creds, method => 'filter', follow => (join ',', @{$user_id_of}{@target_users}), use_compression => 1, timeout => 45, on_tweet => sub { my $tweet = shift; my ($user, $text) = ($tweet->{user}->{screen_name}, $tweet->{text}); return if none { defined } $user, $text; return if none { $user eq $_ } @target_users; syslog('info' => encode_utf8("$user: $text\n")); }, on_error => sub { my $error = shift; syslog('warn' => "ERROR: $error\n"); closelog(); $done->send; }, on_eof => sub { closelog(); $done->send; }, ); $done->recv; __END__ --- creds: consumer_key: thisisadummystringsodonotusethis consumer_secret: thisisadummystringsodonotusethis access_token: &token thisisadummystringsodonotusethisoryouwillgetnothing access_token_secret: &token_secret thisisadummystringsodonotusethisoryouwillgetnothing token: *token token_secret: *token_secret target_users: - Kantei_Saigai - tenkijp_jishin |
Streaming APIでツイートを取得するためのモジュールとして、日本のPerlハッカーとして有名なmiyagawaさんが作成されたAnyEvent::Twitter::StreamというモジュールがCPANで公開されていますので、今回はこれを使用します。プログラムの処理としては、あらかじめ設定したユーザーのツイートをリアルタイムに取得し、そのままsyslogメッセージとしてローカルホスト上のsyslogデーモンへ送信するだけの、非常に単純な内容です。なお、Twitterの開発者向けコントロールパネル上で、事前にアプリケーションの登録とAPI Consumer Key等の設定を行っておく必要があります(ここではその方法を割愛します)。設定したConsumer Key等は、プログラムのDATA
セクションに記載します。
Streaming APIでツイートを取得するにあたり、取得したいユーザーのuser ID
をAPIの引数として渡す必要がありますが、user ID
は通常、Twitterクライアント上から確認することができません(実際には、Webブラウザ上でtwitter.comにアクセスし、HTMLのソースを見ることで確認可能です)。今回のプログラムでは、ツイートを取得したいユーザー(target_users
、今回は”首相官邸(災害情報)“と”tenki.jp地震情報“の2つ)のスクリーンネームからuser ID
を自動的に取得するよう、起動時に一度だけREST APIを呼び出しています。なお、ツイートを取得したいユーザーを、自身のTwitterアカウントであらかじめフォローしておく必要があります。
プログラムの主な処理としては、AnyEventのイベントループ中にツイートを取得した場合(on_tweet
)、あらかじめ設定したユーザー(target_users
)本人のツイートなら(つまり、他ユーザーからのリツイートでなければ)、ツイートの内容をsyslogメッセージとしてローカルホスト上のsyslogデーモンへ転送します。なお、syslogデーモン側では、あらかじめUDPでsyslogメッセージを受け付け、それをHinemosマネージャへ転送するよう設定しておく必要があります。通常、Hinemosエージェントをインストールすることでこの設定が自動的に行われますので、今回は特に設定変更する必要はありませんでした。
エージェントサーバ上で上記のプログラムを実行すれば、エージェントサーバ側での準備は完了となります(もちろん、マネージャサーバ上で行うことも可能です)。なお、上記のプログラムは、実行中はツイートを延々と取得し続けますが、サンプルプログラムのため、異常終了時の再実行等は考慮しておりませんのでご注意ください。
引き続き、Hinemosのシステムログ監視を設定します。以下は設定例です。
上記では、tenki.jp地震情報のツイートに必ず含まれると思われる”最大震度n”をパターンマッチングの条件として、重要度”危険”で検知するよう設定しています。なお、上記はテストのため、震度1~9を全て”危険”としていますが、実際には震度に応じて重要度を細かく設定すると良いでしょう。
以上で、全ての設定が完了しました。あとは、ツイートが来るのを待つだけです。実際にHinemosで検知したツイートは以下になります。
上記ではイベント通知を使用しましたが、特に重要なツイートであればメール通知を使用したり、ツイートを検知した時に何らかの処理を行わせたい場合にはコマンド通知やジョブ通知を使用する等、様々な利用方法が考えられます。
以上、簡単ですがTwitterとHinemosに関する話題をご紹介しました。