2018年8月12日 星期日

syslog: syslog() and syslogd

syslog 收集應用程式和 Kernel 產生的執行紀錄,執行紀錄含有分類和等級,讓系統管理員好監控管理。
  • 標準函數 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。
註:glibc 提供 klogctl() 使用系統呼叫 syslog()。
擷取自 TLPI Figure 37-1

syslog API

#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 系統都會正常。如果 syslog 系統出錯,那也就無處回報,系統管理員應該會先注意到。

syslog() 或 vsyslog()  產生紀錄,priority 是分類和等級的 OR 組合,format 之後的參數和 printf() 和 vprintf() 仝款,不同的是 syslog() 會自動在最後加上換行,另外「%m」會取代為目前 errno 的錯誤字串,相當於 strerror(errno)。
分類 (facility)名稱說明
0LOG_KERNkern來自 Kernel。user process 使用會轉為 user。
1LOG_USERuser來自 user process (預設)
2LOG_MAILmail來自郵件系統。
3LOG_DAEMONdaemon來自其它系統 daemons。
4LOG_AUTHauth (security)Security 或 authorization 訊息 (e.g., su)
5LOG_SYSLOGsyslog來自 syslogd 內部。
6LOG_LPRlpr來自印表機系統 (lpr, lpd, lpc)。
7LOG_NEWSnews來自 Usenet 網路新聞。
8LOG_UUCPuucp來自 UUCP 系統
9LOG_CRONcron來自 cron 和 at daemons。
10LOG_AUTHPRIVauthprivPrivate 的 security 或 authorization 訊息。訊息包含密碼或其它敏感資訊位置不同於 LOG_AUTH。
11LOG_FTPftp來自 ftpd。
16
~
23
LOG_LOCAL0
~
LOG_LOCAL7
local0
~
local7
保留為本機使用。

等級 (level)名稱說明
0LOG_EMERGemerg (panic)系統當機或無法使用
1LOG_ALERTalert需要立即處理 (例如系統資料庫毀壞)
2LOG_CRITcrit危急發生 (例如硬碟裝置錯誤)
3LOG_ERRerr (error)錯誤發生
4LOG_WARNINGwarning (warn)警告發生
5LOG_NOTICEnotice正常,但需要注意
6LOG_INFOinfo一般資訊
7LOG_DEBUGdebug除錯訊息


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() 未指定時的預設分類。
closelog():關閉 /dev/log。如果 daemon 持續在跑並不需要。

過濾 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

參考

  1. 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。
    • 動作是執行程式?

沒有留言:

張貼留言

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...