XMLRPC::Transport::HTTP のロギング
XMLRPC::Transport::HTTP::Daemonでサーバ作っってたらログの取り方でとても困った。小汚い方法でなんとかなったけども、もっとスマートな方法を誰か教えてくれないかなーと淡い期待をこめて晒しておく。
SOAP::Liteを継承したモジュールでログを取ろうと思ったら、SOAP::Traceを使うのが常套手段な訳だけど、実はこいつに用意されてるイベント(フックポイント)のいくつかはXMLRPC::Transport::* では使えない。これはenvelopeメソッドをXMLRPC::Liteでオーバーライドしてるからだと思う。
僕はどうしてもfaultログを取りたかったんだけど、こんなことをしておいてもなーんにも記録されない。
use XMLRPC::Transport::HTTP; use Sys::Syslog qw(:DEFAULT setlogsock); setlogsock 'unix'; openlog($0, 'cons,pid', 'local0'); SOAP::Lite->import( +trace => [ fault => sub { syslog('err', sprintf('Fault code:%s, string:%s', @_)); }, ]); my $server = XMLRPC::Transport::HTTP::Daemon->new( 〜〜省略〜〜 $server->handle;
今畜生め。そこで僕の取った方法は XMLRPC::Transport::HTTP::Daemon::make_fault を上書きして、フックポイントをねじこむ。
{ no warnings 'redefine'; my $org = XMLRPC::Transport::HTTP::Daemon->can("make_fault"); *XMLRPC::Transport::HTTP::Daemon::make_fault = sub { my @save = @_; # syslog()に何故か@_が破壊されるので、保全しておく。 SOAP::Trace::fault(@_[1, 2]); # callback関数に渡す。 $org->(@save); }; }
追記:tokuhiromさんとこで見たやり方だと。忘れないようにメモっておく。これでもいいんだー。シンボルテーブルを参照するのね。
my $org = *XMLRPC::Transport::HTTP::Daemon::make_fault{CODE};
こうしておけばリクエストがfaultしたときに、ログが取れるようになる。
が、どうなんだろうこれ。普通にパブリックなインターフェースを通してログとれないのかな。
他にもリクエストのメソッド名とかパラメーターとかもログとってるんだけど、れそぞれの取得方法に一貫性がない…。使わせて頂いておいてあれなんだが、ちょっと疑問を感じるインターフェースなきがした。あと、peer_addrはどうしても取れなかった。