syslogd和klogd是很有意思的守護程序,syslogd是乙個分發器,它將接收到的所有日誌按照/etc/syslog.conf的配置策略傳送到這些日誌應該去的地方,當然也包括從klogd接收到的日誌,klogd首先接收核心的日誌,然後將之傳送給syslogd,klogd是怎麼接收核心的日誌,接收到的日誌又是怎麼發給syslogd的呢?過程其實很簡單,klogd通過讀取/proc/kmsg來接收核心的日誌,通過strace -p可以看到:
read(0, "<6>acpi: pci interrupt 0000:05:0"..., 4095) = 95
time([1278013550]) = 1278013550
write(1, "<6>jul 1 15:45:50 kernel: acpi:"..., 97) = 97
為了看清楚0和1分別代表什麼,看一下/proc檔案系統:
ll /proc/xx/fd/
total 3
lr-x------ 1 root root 64 2010-07-01 15:43 0 -> /proc/kmsg
lrwx------ 1 root root 64 2010-07-01 15:43 1 -> socket:[7974]
lr-x------ 1 root root 64 2010-07-01 15:43 2 -> /boot/system.map...
或者通過lsof -p xx檢視也是可以的。經過解析命令的輸出,發現klogd從/proc/kmsg中讀取了核心資訊,然後寫入了乙個套接字,這個套接字的另一端肯定是syslogd使用的套接字,並且syslogd肯定從該套接字的另一端接收了資料,用strace和lsof/ll /proc/yy/fd/證實一下:
ll /proc/yy/fd
total 18
lrwx------ 1 root root 64 2010-07-01 15:21 0 -> socket:[4146]
l-wx------ 1 root root 64 2010-07-01 15:21 1 -> /var/log/auth.log
...l-wx------ 1 root root 64 2010-07-01 15:21 8 -> /var/log/uucp.log
l-wx------ 1 root root 64 2010-07-01 15:21 9 -> /var/log/mail.info
確實是這樣的,syslogd中確實使用了乙個套接字,為了證實確實從該套接字接收到了klogd發來的資料,在兩個終端上同時strace -p syslogd和klogd,然後載入乙個驅動或者自己寫乙個printk的核心模組,然後觀察兩個終端的輸出,確實klogd從0讀出了資訊abc,然後寫入了1,syslogd從0讀出了abc,然後寫入了乙個配置好的日誌檔案,它們之間是通過套接字來完成通訊的。同樣的,庫函式syslog將klogd的大致過程進行了封裝,這樣任何程式都可以呼叫syslog函式進行日誌記錄了,syslogd成了整個系統統一的乙個日誌記錄器,下面是在syslog的manpage上得到的函式原型:
void openlog(const char *ident, int option, int facility); //ident設定為乙個可被過濾的特徵字串,一般為應用程式的名字
void syslog(int priority, const char *format, ...);
void closelog(void);
此處的syslog庫函式內部實現的就是套接字傳送過程,沒有什麼好說的,可是千萬不要將這個syslog和linux的系統呼叫sys_syslog搞混淆了,後者的原型是:
asmlinkage long sys_syslog(int type, char __user *buf, int len);
而dmesg呼叫的正是這個函式,該函式內部通過type分成了若干個型別,其實klogd也是可以通過直接呼叫這個函式來實現的(/proc/kmsg的read方法就是呼叫do_syslog,而sys_syslog也是呼叫do_syslog)。
syslogd和syslog庫函式中使用的套接字就是unix族套接字,是unix本地程序間通訊的一種好辦法,這種套接字必須有一對,本質上實現了乙個管道,在介面和語義上又和bsd套接字相統一,實際上bsd套接字沒有網路的概念,它只承認自己可以實現程序間通訊,它將網路通訊也統一看作了程序間通訊,只是後來的af_inet等實現的不同機器間的程序間通訊,而原始的af_unix實現的是本機的程序間通訊。既然af_unix實現了本機的程序間通訊,那麼它的位址只需要本機內唯一即可,因此採用普通檔案是乙個不錯的選擇,其位址就是檔案的全路徑:
struct sockaddr_un ;
比如syslogd使用的/dev/log就是乙個處於一般檔案系統的套接字。套接字建立函式socket的第二個引數是型別,af_unix族的套接字也分stream型別和datagram型別,只是在語義約束上鬆了很多,datagram僅僅在資料邊界等不多的方面和stream型別的套接字有區別,有無連線的概念已經退化了。不管是stream還是datagram型別的af_unix套接字,send的本質就是將資料放入接收者的接收佇列,recv則相反。
上述套接字和管道的區別是什麼?僅僅是使用時的語義不同,管道的約束很少,也不很規範,很難擴充套件,而套接字擁有位址空間的概念,有協議的概念,很容易進行擴充套件,並且語義也很清晰。也正是這種統一,使得syslog很容易支援遠端日誌記錄,本機日誌記錄和遠端記錄都使用套接字,所不同的只是套接字的位址族不同,這樣很多編碼都可以引數化,配置化,不必再寫冗餘的**了。
syslog的點滴 集中處理日誌
syslogd和klogd是很有意思的守護程序,syslogd是乙個分發器,它將接收到的所有日誌按照 etc syslog.conf的配置策略傳送到這些日誌應該去的地方,當然也包括從klogd接收到的日誌,klogd首先接收核心的日誌,然後將之傳送給syslogd,klogd是怎麼接收核心的日誌,接...
syslog日誌的型別和級別
syslog日誌的型別和級別 名稱 描述 0 kern 核心 1 user 使用者級 2 mail 郵件 3 daemon 系統 4 auth 安全與授權 5 syslog 守護程序 6 lpr 列印相關 7 news 網路訊息 8 uucp uucp子系統 9 時鐘 10 authpriv 安全與...
日誌集中化處理架構搭建 參與討論,贏取禮品
日誌集中化處理架構搭建 參與討論,贏取禮品 集中化的日誌處理對大規模分布式系統極為重要,可以很大程度上降低業務系統運維的難度。如何搭建一套集中化的日誌處理框架,來滿足對大規模分布式系統集中日誌管理的需求?如何儲存超大的日誌容量?如何在海量的日誌資料中找到自己需要的內容?如何滿足在高流量下的日誌實時分...