HAYAGUI

FreeBSD 4.7 + syslog

はじめに

システム内で動いている Daemon プロセスは、 「動いているよ」とか「エラーがあったよ」というレスポンスを要求しない情報をログとして syslogd を経由して /var/log 以下に保存します。このページでは、ログについていろいろ勉強します。

FreeBSD 4.7 manual : syslog.conf
FreeBSD 4.7 manual : syslogd
FreeBSD 4.7 manual : logger

syslogの仕組み

Daemon が openlog( ),syslog( ),closelog( )関数を使用してログを保存する時、ログ送信元を意味する「ファシリティ」と、 ログの重要度を意味する「レベル(引数名はpriority)」を渡します。
SYSLOG(3)

     #include <syslog.h>
     #include <stdarg.h>

     void
     syslog(int priority, const char *message, ...);

     void
     openlog(const char *ident, int logopt, int facility);

     void
     closelog(void);
FreeBSD 4.7 のファシリティの種類は次の24種類です。

auth 認証メッセージ
authpriv プライベートな認証メッセージ。
console コンソールから出力されるメッセージ
daemon daemon メッセージ
cron cron メッセージ
ftp ftp メッセージ
kern ローカルのカーネルメッセージ。
ローカルでない場合は user に変換される。
lpr lpr メッセージ
mail メールメッセージ
mark 20分毎に ``info'' の優先度を持つメッセージ。システム用
news ニュースメッセージ
ntp 時刻補正メッセージ
security security メッセージ
syslog syslog メッセージ
user ユーザプロセスメッセージ
uucp uucp メッセージ
local0 から local7 ユーザ定義用

FreeBSD 4.7 のレベルの種類は次の8種類です。

emerg 非常事態
alert すぐに対応が必要
crit 重大なエラー
err エラー
warning 注意
notice 重要な情報
info 情報
debug デバッグ

syslog( ) が実行されると、syslogd は /etc/syslog.conf に設定された内容に基づき保存先と保存内容を制御します。

> pwd
/etc
> cat syslog.conf
*.err;kern.debug;auth.notice;mail.crit          /dev/console
*.notice;kern.debug;lpr.info;mail.crit;news.err /var/log/messages
security.*                                      /var/log/security
auth.info;authpriv.info                         /var/log/auth.log
mail.info                                       /var/log/maillog
lpr.info                                        /var/log/lpd-errs
cron.*                                          /var/log/cron
*.emerg                                         *
!startslip
*.*                                             /var/log/slip.log
!ppp
*.*                                             /var/log/ppp.log

この書式は、以下の様になります。

ファシリティ.レベル     出力先
ここで設定された「レベル」は、「そのレベルだけ」ではなく「そのレベル以上すべて」という意味である。 たとえば、 err の場合は、err,crit,alert,emerg を指します。
その他に以下のような設定があります。
  • ファシリティとレベルの所に * を使用すると、「全部」という意味になります。
  • ファシリティの前にある ! は、出力先を他と共有するときに設定します。
  • 出力先に * にある場合は、「すべてのユーザが受け取る」という意味です。
  • 出力先にユーザ名(root等)がある場合は、そのユーザ宛てに送信する意味になります。
  • 出力先に「@hoge.hayagui.com」という場合は、syslogを動かしている他のホストに送信する意味になります。
  • 出力先に 「|prog 」という場合は、prog というプログラムの標準入力につなぐ事を意味します。

/var/log 以下を見てみます。

> pwd
/var/log
> ls
adduser         lastlog         ppp.log         sendmail.st.1
auth.log        lpd-errs        security        sendmail.st.2
cron            maillog         sendmail.st     slip.log
cups            messages        sendmail.st.0   wtmp
ログを作成する場合は、指定されたディレクトリにあらかじめファイルがある必要があり、 touch などでファイルを作成しておく必要があります。反対に、ファイルが無いとログは作成されません。
cups など syslog を使用しないものも、ログの保存に /var/log を使用します。

保存されるログは、以下のような感じです。

mico# tail messages
Aug 20 08:05:31 mico /kernel: plip0:  on ppbus0
Aug 20 08:05:31 mico /kernel: lpt0:  on ppbus0
Aug 20 08:05:31 mico /kernel: lpt0: Interrupt-driven port
Aug 20 08:05:31 mico /kernel: ppi0:  on ppbus0
Aug 20 08:05:31 mico /kernel: ad0: DMA limited to UDMA33, non-ATA66 cable or device
Aug 20 08:05:31 mico /kernel: ad0: 4126MB  [8944/15/63] at ata0-master UDMA33
Aug 20 08:05:31 mico /kernel: acd0: CD-RW  at ata0-slave PIO4
Aug 20 08:05:31 mico /kernel: Waiting 15 seconds for SCSI devices to settle
Aug 20 08:05:31 mico /kernel: Mounting root from ufs:/dev/ad0s1a
Aug 20 08:27:04 mico su: kenz to root on /dev/ttyp0
書式は、次のようになります。

曜日 日 時:分:秒 ホスト名 送信元: ログ内容

ログを出力してみよう

logger を使ってログに出力してみます。
> logger -p local0.notice "hogehoge"
と実行すると、 /etc/syslog.conf で以下の様に設定されている為、
*.notice;kern.debug;lpr.info;mail.crit;news.err /var/log/messages
/var/log/messages に保存されます。
> tail messages
Aug 20 08:05:31 mico /kernel: lpt0:  on ppbus0
Aug 20 08:05:31 mico /kernel: lpt0: Interrupt-driven port
Aug 20 08:05:31 mico /kernel: ppi0:  on ppbus0
Aug 20 08:05:31 mico /kernel: ad0: DMA limited to UDMA33, non-ATA66 cable or device
Aug 20 08:05:31 mico /kernel: ad0: 4126MB  [8944/15/63] at ata0-master UDMA33
Aug 20 08:05:31 mico /kernel: acd0: CD-RW  at ata0-slave PIO4
Aug 20 08:05:31 mico /kernel: Waiting 15 seconds for SCSI devices to settle
Aug 20 08:05:31 mico /kernel: Mounting root from ufs:/dev/ad0s1a
Aug 20 08:27:04 mico su: kenz to root on /dev/ttyp0
Aug 20 10:21:07 mico kenz: hogehoge
こんな感じ。

次に、syslog() を使ってログを出力します。

次のようなプログラムを作成します。

> cat syslogtest.c
#include <syslog.h>

int main()
{
  openlog("local0", LOG_NDELAY | LOG_PID, LOG_LOCAL0);
  syslog(LOG_NOTICE, "hogehoge abc test");
  closelog();

  return 0;
}

コンパイルして実行。
> gcc -o syslogtest syslogtest.c
> ./syslogtest
こんな感じに出力される。
mico# tail /var/log/messages
Aug 20 08:05:31 mico /kernel: ppi0:  on ppbus0
Aug 20 08:05:31 mico /kernel: ad0: DMA limited to UDMA33, non-ATA66 cable or device
Aug 20 08:05:31 mico /kernel: ad0: 4126MB  [8944/15/63] at ata0-master UDMA33
Aug 20 08:05:31 mico /kernel: acd0: CD-RW  at ata0-slave PIO4
Aug 20 08:05:31 mico /kernel: Waiting 15 seconds for SCSI devices to settle
Aug 20 08:05:31 mico /kernel: Mounting root from ufs:/dev/ad0s1a
Aug 20 08:27:04 mico su: kenz to root on /dev/ttyp0
Aug 20 10:21:07 mico kenz: hogehoge
Aug 20 10:33:32 mico local0[339]: hogehoge abc test

出力先を変えてみよう

/etc/syslog.conf で設定している出力先を変更してみます。

ユーザにメッセージを送信
出力先に root を設定します。
*.notice;kern.debug;lpr.info;mail.crit;news.err root
その後、syslogd にシグナルを送って再起動。
mico# kill -HUP `cat /var/run/syslog.pid `
先ほどの syslogtest を実行すると、root のコンソールにメッセージが表示されました。 ただし、telnet している root には届きません。

成功。

他のホストに送信
出力先にホスト名を設定します。
*.notice;kern.debug;lpr.info;mail.crit;news.err @eden.hayagui.com
その後、syslogd にシグナルを送って再起動。
mico# kill -HUP `cat /var/run/syslog.pid `
次に、ログを受け取るホストを設定します。通常は -s オプションがついてログを受け取らない設定になっていますので、
eden# ps -ax | grep syslogd
   70  ??  Ss     0:00.09 /usr/sbin/syslogd -s
syslogd を kill した後、192.168.0.7/24 から送信される syslog を受け付けるように設定して起動。
eden# kill -9 70
eden# /usr/sbin/syslogd -a 192.168.0.7/24
eden# ps -ax | grep syslogd
  438  ??  Is     0:00.03 /usr/sbin/syslogd -a 192.168.0.7/24
先の syslogtest を実行すると、以下の様になります。
Aug 20 11:01:31 mico local0[386]: hogehoge abc test
成功成功。

他のプログラムにつなぐ
ログを netcat に繋いで udp でサーバに投げるようにしてみました。
/etc/syslog.conf は、このように書きます。192.168.0.8 の 12345 ポートに送信する内容です。
*.notice;kern.debug;lpr.info;mail.crit;news.err |/usr/local/bin/nc -u -w 2 192.168.0.8 12345
次に、サーバ側で受け付けます。
eden# nc -l -u -p 12345
その後、syslogtest を実行すると、サーバにメッセージが届きました。
Aug 20 11:12:37 mico local0[462]: hogehoge abc test
成功成功成功。
おもしろいなー。

ちょい実験

他のsyslogに保存する設定の場合、クライアントからサーバにはどのようなデータが飛んでくるのかを調査。

サーバ側の syslogd を kill して、nc で UDP/514 をあけて待っておく。

eden# nc -u -l -p 514
クライアント側で、syslogtest を実行すると、こんな感じのパケットが届く。
eden# nc -u -l -p 514
<133>Aug 21 12:08:52 local0[131]: hogehoge abc test
先頭の <133> は、ファシリティとプライオリティを表します。

133 を2進数で表すと、10000101 になります。 下位3ビットの 101 がプライオリティの LOG_NOTICE を識別し、 上位の 10000 がファシリティの local0 を識別します。

/usr/include/syslog.h の一部。

#define LOG_EMERG       0       /* system is unusable */
#define LOG_ALERT       1       /* action must be taken immediately */
#define LOG_CRIT        2       /* critical conditions */
#define LOG_ERR         3       /* error conditions */
#define LOG_WARNING     4       /* warning conditions */
#define LOG_NOTICE      5       /* normal but significant condition */
#define LOG_INFO        6       /* informational */
#define LOG_DEBUG       7       /* debug-level messages */

#define LOG_PRIMASK     0x07    /* mask to extract priority part (internal) */
                                /* extract priority */
#define LOG_PRI(p)      ((p) & LOG_PRIMASK)
#define LOG_MAKEPRI(fac, pri)   ((fac) | (pri))


/* facility codes */
#define LOG_KERN        (0<<3)  /* kernel messages */
#define LOG_USER        (1<<3)  /* random user-level messages */
#define LOG_MAIL        (2<<3)  /* mail system */
#define LOG_DAEMON      (3<<3)  /* system daemons */
#define LOG_AUTH        (4<<3)  /* authorization messages */
#define LOG_SYSLOG      (5<<3)  /* messages generated internally by syslogd */
#define LOG_LPR         (6<<3)  /* line printer subsystem */
#define LOG_NEWS        (7<<3)  /* network news subsystem */
#define LOG_UUCP        (8<<3)  /* UUCP subsystem */
#define LOG_CRON        (9<<3)  /* clock daemon */
#define LOG_AUTHPRIV    (10<<3) /* authorization messages (private) */
                                /* Facility #10 clashes in DEC UNIX, where */
                                /* it's defined as LOG_MEGASAFE for AdvFS  */
                                /* event logging.                          */
#define LOG_FTP         (11<<3) /* ftp daemon */
#define LOG_NTP         (12<<3) /* NTP subsystem */
#define LOG_SECURITY    (13<<3) /* security subsystems (firewalling, etc.) */
#define LOG_CONSOLE     (14<<3) /* /dev/console output */

        /* other codes through 15 reserved for system use */
#define LOG_LOCAL0      (16<<3) /* reserved for local use */
#define LOG_LOCAL1      (17<<3) /* reserved for local use */
#define LOG_LOCAL2      (18<<3) /* reserved for local use */
#define LOG_LOCAL3      (19<<3) /* reserved for local use */
#define LOG_LOCAL4      (20<<3) /* reserved for local use */
#define LOG_LOCAL5      (21<<3) /* reserved for local use */
#define LOG_LOCAL6      (22<<3) /* reserved for local use */
#define LOG_LOCAL7      (23<<3) /* reserved for local use */

#define LOG_NFACILITIES 24      /* current number of facilities */
#define LOG_FACMASK     0x03f8  /* mask to extract facility part */
                                /* facility of pri */
#define LOG_FAC(p)      (((p) & LOG_FACMASK) >> 3)
参考:BSD syslogプロトコル(http://www.amris.co.jp/netdocs/rfc3164_j.html)

Windows Syslog Daemon

WindowsPCを、外部 Syslog Daemon として利用する場合、Kiwi Syslog Daemon が便利です。 無料だし。日本語のマニュアルあるし。

ファイルはここから get します。
http://www.kiwisyslog.com

Service として動作させるプログラムと、単発アプリケーションとして動作させるプログラムの二つありますので、使用環境に合わせて選択してください。

使い方は、いたって簡単。ただ起動させるだけ。

日本語マニュアル PDF (http://www.kiwitools.com/downloads/Japanese_Syslogd.pdf)

単純に SYSLOG パケットを受けるだけではなくて、受けた後のアクションとしてメール送信などができたりします。

でも、単純にSYSLOGのUDPパケットを受けるだけなら、Netcat for Windows でもさくっとできるけどね。 (C:\nc> nc.exe -l -u -p 514)


戻る



(C)1999 - 2003 Kenji Ito All rights reserved.