【Perl】 Log::Dispatchで、TCP経由でsyslogを送信する際の注意点

投稿日: / 更新日:

この記事は2年以上前に書かれたものです。情報が古い可能性があります。

少し前に、TCP経由でsyslogメッセージを送信するプログラムを作成する必要があり、Perlでそれを作成したのですが、その時にちょっとした罠に引っかかってしまったので、備忘録の意味合いも込めてご紹介したいと思います。

2012/08/19追記: Sys::Syslogの最新版では、ここでご紹介したバグが修正されています。こちらもご覧ください。

Perlでログを出力させたい場合、良く使われるフレームワークとしてLog::Dispatchがあります。このモジュールを使用することで、ファイルや画面、メールやsyslogなど、様々な出力先へ簡単にログを出力することができます。

以下は、Log::Dispatchを使用した簡単なサンプルスクリプトです。

使用法は以下のとおりです。なお、-dオプションを使用すると、指定したホスト上のsyslogデーモンへ直接メッセージを送信することができます。

しかし、以下のようにtcpでsyslogを送信しようとすると、エラーが発生してしまいます。

Log::Dispatch::Syslogの75行目辺りを見ると、次のようになっています。

ここで、Sys::Syslogというモジュールの、setlogsockというサブルーチンの呼び出しに失敗した模様です。モジュール側の実装を見てみます。

getservbyname関数を使用して、syslogサービスがシステムに登録されているかどうかを確認し、またポート番号を取得しようとしています。私の環境(CentOS 6.2)では、次のようになっていました。

上記のように、tcpのsyslogサービスに関するエントリはそもそも存在しないようです。従って、これはSys::Syslogのバグである可能性があります。CPANモジュールのバグトラッカであるrt.cpan.orgで確認したところ、ほんの数日前に、このバグに関するチケットが登録されていました。

Bug #78044 for Sys-Syslog: Incorrectly requires /etc/services entries for TCP

明らかなバグですが、モジュールのメンテナーが対応しない限り、このままではtcpでsyslogを送信することができません。暫定対処として、やや強引ですが、このモジュールに直接パッチを当てます。差分は以下のとおりです。

これにより、tcpでのsyslogメッセージ送信が無事行えるようになりました。

以上、Perlでのsyslog送信に関する簡単な話題をご紹介しました。

Hinemos導入はアトミテックにお任せください

見積もりを依頼する

最新情報発信中

Xやメルマガでも、Hinemosの保守、
開発、導入、構築やカスタマイズ等の
お役立ち情報を発信しています。
是非ご登録ください。