syslogd和klogd是頗有意思的守護進程,syslogd是一個分發器,它將接收到的全部日誌按照/etc/syslog.conf的配置策略發送到這些日誌應該去的地方,固然也包括從klogd接收到的日誌。klogd首先接收內核的日誌,而後將之發送給syslogd。html
syslogd日誌記錄器由兩個守護進程(klogd,syslogd)和一個配置文件(syslog.conf)組成。klogd不使用配置文件,它負責截獲內核消息,它既能夠獨立使用也能夠做爲syslogd的客戶端運行。syslogd默認使用/etc/syslog.conf做爲配置文件,負責截獲應用程序消息,還能夠截獲klogd向其轉發的內核消息。支持internet/unix domain sockets的特性使得這兩個工具能夠用於記錄本地和遠程的日誌。linux
syslog是lib函數,用於向系統發送日誌(send messages to the system logger)。編程
#include <syslog.h> void openlog(const char *ident, int option, int facility); void syslog(int priority, const char *format, ...); void closelog(void); void vsyslog(int priority, const char *format, va_list ap);
默認的日誌操做步驟爲openlog() -> syslog()/ vsyslog() -> closelog()。ubuntu
openlog()的參數ident指向一個字符串,追加到每條日誌前,用於標記日誌屬主,通常爲程序名,爲NULL時默認是程序名(不統一);dom
option控制log行爲,下列值可OR:socket
LOG_CONS Write directly to system console if there is an error while sending to system logger. LOG_NDELAY Open the connection immediately (normally, the connection is opened when the first message is logged). LOG_NOWAIT Don't wait for child processes that may have been created while logging the message.
(The GNU C library does not create a child process, so this option has no effect on Linux.) LOG_ODELAY The converse of LOG_NDELAY; opening of the connection is delayed until syslog() is called.
(This is the default, and need not be specified.) LOG_PERROR (Not in POSIX.1-2001 or POSIX.1-2008.) Print to stderr as well. LOG_PID Include PID with each message.
facility指定哪一種類型程序在發送日誌,配置文件可指定不一樣facility日誌可進行不一樣處理:ide
LOG_AUTH security/authorization messages LOG_AUTHPRIV security/authorization messages (private) LOG_CRON clock daemon (cron and at) LOG_DAEMON system daemons without separate facility value LOG_FTP ftp daemon LOG_KERN kernel messages (these can't be generated from user processes) LOG_LOCAL0 through LOG_LOCAL7 reserved for local use LOG_LPR line printer subsystem LOG_MAIL mail subsystem LOG_NEWS USENET news subsystem LOG_SYSLOG messages generated internally by syslogd(8) LOG_USER (default) generic user-level messages LOG_UUCP UUCP subsystem
syslog()負責寫日誌,priority指定日誌級別:函數
LOG_EMERG system is unusable LOG_ALERT action must be taken immediately LOG_CRIT critical conditions LOG_ERR error conditions LOG_WARNING warning conditions LOG_NOTICE normal, but significant, condition LOG_INFO informational message LOG_DEBUG debug-level message
man手冊明確指出不要向format傳入用戶數據(Never pass a string with user-supplied data as a format, use the following instead)工具
syslog(priority, "%s", string);
通常應用程序中都要都其進行封裝,以便於直接打印相關級別日誌(封裝LOG_EMERG級別日誌):this
#define BUF_SIZE 1024 char *ident = "hello"; void hello_syslog_emerg(char *format,...) { va_list ptr; char buf[BUF_SIZE] = {0}; // ident null or format message null if(!ident || !format) { return; } openlog(ident, 0, LOG_DAEMON); // put log va_start(ptr, format); vsprintf(buf, format, ptr); va_end(ptr); syslog(LOG_EMERG, "%s", buf); return; }
示例:
#include <stdio.h> #include <stdarg.h> #include <syslog.h> #define BUF_SIZE 1024 char *ident = "hello"; void hello_syslog_emerg(char *format,...) { va_list ptr; char buf[BUF_SIZE] = {0}; // ident null or format message null if(!ident || !format) { return; } openlog(ident, 0, LOG_DAEMON); // put log va_start(ptr, format); vsprintf(buf, format, ptr); va_end(ptr); syslog(LOG_EMERG, "%s", buf); return; } int main(void) { char cbuf[BUF_SIZE] = {0}; printf("send one emergency message to system:\n"); scanf("%s", cbuf); hello_syslog_emerg("%s", cbuf); return 0; }
@ubuntu:~/vmlinux$ gcc hello.c -o hello -Wall @ubuntu:~/vmlinux$ ./hello send one emergency message to system: thesystemisoff @ubuntu:~/vmlinux$ Broadcast message from systemd-journald@ubuntu (Sat 2018-05-12 17:12:50 CST): hello[3786]: thesystemisoff
或宏定義封裝:
#define ERROR(fmt, ...) do { \ syslog(LOG_ERR, "jail: "fmt, ## __VA_ARGS__); \ } while (0)
參考:
1. http://blog.csdn.net/dog250/article/details/5707979
2. http://www.360doc.com/content/13/0102/10/7775902_257612487.shtml