linux日誌:syslogd和klogd及syslog

一. 日誌守護進程

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

相關文章
相關標籤/搜索