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)
戻る
|