- 標準函數 syslog() 將紀錄放到 socket /dev/log。
- daemon syslogd 接收 /dev/log 和 UDP port 514 的訊息,依據設定檔 syslog.conf 中對於分類和等級的規則,選擇將紀錄訊息導到終端機、FIFO、硬碟、遠端、或登入的使用者。
- 遠端可能是另一個 syslogd,更進一步集中紀錄,也可以有備份紀錄的作用。
- process 用標準函數 syslog() 產生紀錄。
- kernel 用 printk() 產生紀錄,經過系統呼叫 syslog() 或 /proc/kmsg 給 daemon klogd 收集。klogd 再呼叫標準函式 syslog()。
- 遠端產生的紀錄傳給 UDP port 514。
![]() |
| 擷取自 TLPI Figure 37-1 |
syslog API
這些函數都沒回傳值,因為會假設 syslog 系統都會正常。如果 syslog 系統出錯,那也就無處回報,系統管理員應該會先注意到。#include <syslog.h> /* 開啟和關閉,非必要 */ void openlog(const char *ident, int option, int facility); void closelog(void); /* 產生紀錄 */ void syslog(int priority, const char *format, ...); void vsyslog(int priority, const char *format, va_list ap);
syslog() 或 vsyslog() 產生紀錄,priority 是分類和等級的 OR 組合,format 之後的參數和 printf() 和 vprintf() 仝款,不同的是 syslog() 會自動在最後加上換行,另外「%m」會取代為目前 errno 的錯誤字串,相當於 strerror(errno)。
| 分類 (facility) | 名稱 | 說明 | |
|---|---|---|---|
| 0 | LOG_KERN | kern | 來自 Kernel。user process 使用會轉為 user。 |
| 1 | LOG_USER | user | 來自 user process (預設) |
| 2 | LOG_MAIL | 來自郵件系統。 | |
| 3 | LOG_DAEMON | daemon | 來自其它系統 daemons。 |
| 4 | LOG_AUTH | auth (security) | Security 或 authorization 訊息 (e.g., su) |
| 5 | LOG_SYSLOG | syslog | 來自 syslogd 內部。 |
| 6 | LOG_LPR | lpr | 來自印表機系統 (lpr, lpd, lpc)。 |
| 7 | LOG_NEWS | news | 來自 Usenet 網路新聞。 |
| 8 | LOG_UUCP | uucp | 來自 UUCP 系統 |
| 9 | LOG_CRON | cron | 來自 cron 和 at daemons。 |
| 10 | LOG_AUTHPRIV | authpriv | Private 的 security 或 authorization 訊息。訊息包含密碼或其它敏感資訊位置不同於 LOG_AUTH。 |
| 11 | LOG_FTP | ftp | 來自 ftpd。 |
| 16 ~ 23 | LOG_LOCAL0 ~ LOG_LOCAL7 | local0 ~ local7 | 保留為本機使用。 |
| 等級 (level) | 名稱 | 說明 | |
|---|---|---|---|
| 0 | LOG_EMERG | emerg (panic) | 系統當機或無法使用 |
| 1 | LOG_ALERT | alert | 需要立即處理 (例如系統資料庫毀壞) |
| 2 | LOG_CRIT | crit | 危急發生 (例如硬碟裝置錯誤) |
| 3 | LOG_ERR | err (error) | 錯誤發生 |
| 4 | LOG_WARNING | warning (warn) | 警告發生 |
| 5 | LOG_NOTICE | notice | 正常,但需要注意 |
| 6 | LOG_INFO | info | 一般資訊 |
| 7 | LOG_DEBUG | debug | 除錯訊息 |
| none | |||
syslog() 用下列方式輸出使用者提供的字串是危險的:
syslog(priority, user_supplied_string);如果使用者提供的字串包含 format specifiers (例如 %s),無法預期造成什麼結果。較安全作法是改用:
syslog(priority, "%s", user_supplied_string);
openlog():改變使用 syslog() 的預設值,開啟 /dev/log。
- ident:每個訊息前要加的字串,通常是程式名稱。NULL 時,glibc 自動用程式名稱,但不是所有實作皆如此。註:openlog() 只複製字串指標,沒複製字串內容。
- option:下列 bit mask 組合。
- LOG_CONS:訊息寫到 /dev/console。
- LOG_PERROR:訊息也寫一份到 standard error。(非 SUSv3 標準)
- LOG_PID:訊息包含 process ID 供辨別。
- LOG_NDELAY 和 LOG_ODELAY (預設 LOG_ODELAY):LOG_ODELAY 在 log 第一個訊息時才連結到 /dev/log。LOG_NDELAY 則是立刻連結到 /dev/log,例如用在 chroot()。chroot() 後 /dev/log 就看不到了,需要事先 LOG_NDELAY openlog(),tftpd 就是如此使用。
- LOG_NOWAIT:不 wait() log 訊息的 child process 建立。在 Linux 並不建立 child process,所以沒作用。
- facility:facility 預設是 LOG_USER,這裡可以提供 syslog() 未指定時的預設分類。
過濾 log 訊息
int setlogmask (int mask_priority );預設不過濾。LOG_MASK() 將 level 轉換成 mask_priority 用的 bit mask,訊息 level 不在目前的 mask_priority 會丟棄。回傳原本的 mask_priority。
setlogmask(LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) | LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ERR));大部份實作也提供 LOG_UPTO(),建立特定 level 以上的 mask_priority:
setlogmask(LOG_UPTO(LOG_ERR));
logger 指令
logger 是用指令方式產生紀錄訊息到 syslog,可指定 level、ident 等。設定檔 /etc/syslog.conf
/etc/syslog.conf 是 syslogd 的設定檔,內容格式如下:facility.level action # 註解設定符合 facility.level 的訊息所要進行的動作 (action)。facility 指定分類,「*」表示全部。level 指定某個等級以上,其中 debug 是最低的,表示所有等級,有些實作 (包括 Linux) 也可以用「*」。等級 none 則排除符合的分類。多個 facility.level 可用「;」隔來共用 action。一些例子:
*.err /dev/tty10
auth.notice root
*.debug;mail.none;news.none -/var/log/messages
action 可能是
- 檔案。寫入的檔案,前置「-」表示每次寫入不進行 sync (TLPI §13.3),可以有較快的寫入速度,但當機可能會造成資料流失。
- 裝置。特定終端機 /dev/tty10 console device
- 使用者名稱。如 root 登入的終端機。
- 遠端主機
修改 syslog.conf 後,需要送 SIGHUP 叫 syslogd 重新初始化:
$ killall -HUP syslogd
參考
- TLPI §37.5 全部
- man-page syslog.conf(5) (不存在?)
- OpenWrt AA 以前用 busybox syslogd 和 logread,BB 以後用 ubox logd 和 logread。
- RFC 5424: The Syslog Protocol
- 限制:
- http://linux.vbird.org/linux_basic/0570syslog.php
- http://taiwanwolf.blogspot.com/2011/08/centos-6-rsyslogd-log.html
- journald
- 思考
- 一種儲存 log 的方式或者檔案系統,隨時存 log、當機不會造成損毀,又盡量延長 flash 使用壽命。
- log merge:隨著進展,更新某項 log 內容,只需要最後的情況。
- 非文字的 log。
- 動作是執行程式?

沒有留言:
張貼留言