zoukankan      html  css  js  c++  java
  • linux日志:syslogd和klogd及syslog

    一. 日志守护进程

    syslogd和klogd是很有意思的守护进程,syslogd是一个分发器,它将接收到的所有日志按照/etc/syslog.conf的配置策略发送到这些日志应该去的地方,当然也包括从klogd接收到的日志。klogd首先接收内核的日志,然后将之发送给syslogd。

    syslogd日志记录器由两个守护进程(klogd,syslogd)和一个配置文件(syslog.conf)组成。klogd不使用配置文件,它负责截获内核消息,它既可以独立使用也可以作为syslogd的客户端运行。syslogd默认使用/etc/syslog.conf作为配置文件,负责截获应用程序消息,还可以截获klogd向其转发的内核消息。支持internet/unix domain sockets的特性使得这两个工具可以用于记录本地和远程的日志。

    二. 日志应用编程

     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()。

    openlog()的参数ident指向一个字符串,追加到每条日志前,用于标记日志属主,一般为程序名,为NULL时默认是程序名(不统一);

    option控制log行为,下列值可OR:

    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日志可进行不同处理:

    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级别日志):

    #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:
    ");
        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

  • 相关阅读:
    STL——increment/decrement/dereference操作符
    STL——静态常量整数成员在class内部直接初始化
    STL——临时对象的产生与运用
    C++中模板类使用友元模板函数
    模板编程中的技巧
    plsql 表数据中文显示乱码(配置环境变量)
    plsql 常用快捷键(自动替换)
    javascript 跳出(终止)forEach循环
    plsql 快捷键配置
    plsql oracle client没有正确安装(plsql连接远程数据库)
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/5201158.html
Copyright © 2011-2022 走看看