zoukankan      html  css  js  c++  java
  • Unix/Linux syslogd守护进程 & 日志记录syslog

    1. syslogd守护进程

    我们知道, 守护进程(daemon)是

    在后台运行且不与任何控制终端关联的进程.

    参见: Linux 系统编程学习笔记 - 终端、作业控制与守护进程 守护进程章节.

    那么如何得知守护进程的状态, 和某些事情发生呢?守护进程如何输出消息, 或者告知管理员?
    可以调用syslog函数输出这些消息, 函数把消息发送给syslogd守护进程, 而syslogd守护进程可以将消息写入同一个文件或者发送至另一个主机, 方便系统管理人员查看.

    1.1 BSD syslog组织结构:


    有以下3种产生日志消息的方法:
    1)内核例程调用log函数
    任何一个用户进程都可以通过open, read /dev/klog设备来读取这些消息. 不过, 编写内核例程时, 才会用到.

    2)大多数用户进程(守护进程)调用syslog(3)函数来产生日志消息
    3)本机上的用户进程, 或者网络上的用户进程, 都可以通过TCP/IP网络连接到此主机, 可将日志消息发向UDP port 514.
    syslog函数本身不会产生UDP数据报, 而是要求产生此日志消息的进程进行显式的网络编程.

    1.2 syslogd守护进程的启动

    syslond守护进程是由某个系统初始化脚本启动, 而且在系统工作期间一直运行.
    源自Berkeley的syslogd的启动实现步骤:
    1)读取配置文件
    通常为/ect/syslog.conf 的配置文件指定本守护进程可能收取的各种日志消息(log message)应该如何处理. 这些消息可能被添加到一个文件(特例/dev/console), 或被写到指定用户的登录窗口(若该用户已登录到本守护进程所在系统中), 或被转发给另一个主机上的syslogd进程.

    2)创建一个Unix Domain数据报套接字, 给他捆绑路径名/var/run/log(某些系统是/dev/log)

    3)创建一个UDP套接字, 捆绑端口514(syslog服务使用端口号)

    4)打开路径名/dev/klog
    来自内核中的任何出错消息看着像是这个设备的输入.

    5)此后, syslogd守护进程在一个无限循环中运行: 调用select以等待它的3个描述符(来自上面的1),2),3))之一可读, 读入日志消息, 并按照配置文件进行处理. 如果守护进程收到SIGHUP信号, 那么就重新读取配置文件.

    注意: 较新的syslogd实现禁止创建UDP套接字, 除非管理员明确要求. 理由: 允许任何进程往该套接字发送UDP数据报, 会让系统易遭拒绝服务攻击, 其文件系统可能被填满, 而合法进程的日志消息可能被排挤掉.


    2. 日志记录函数

    2.1 syslog

    守护进程没有控制终端, 不能打印消息到stdout, stderr. 用户进程从syslogd守护进程中登记消息的常用方法是调用syslog函数.
    调用syslog产生一个日志消息.

    #include <syslog.h>
    
    void syslog(int priority, const char *format, ...);
    
    • 参数
      priority 是facility和level的组合. level见下表, facility见openlog的facility.

    syslog的level:

    level 说明
    LOG_EMERG 紧急(系统不可使用)(最高优先级)
    LOG_ALERT 必须立即修复的情况
    LOG_CRIT 严重情况(如硬件设备出错)
    LOG_ERR 出错情况
    LOG_WARNING 警告情况
    LOG_NOTICE 正常但重要的情况
    LOG_INFO 信息性消息
    LOG_DEBUG 调试消息(最低优先级)

    2.2 openlog, closelog

    #include <syslog.h>
    
    void openlog(const char *ident, int option, int facility);
    void closelog(void);
    void vsyslog(int priority, const char *format, va_list ap);
    

    openlog 可选调用, 如果不调用openlog, 则在第一次调用syslong时, 自动调用openlog. openlog可以在首次调用syslog前调用.
    closelog 可选调用, 因为它只是关闭曾被用于与syslogd守护进程进行通信的描述符. 这些描述符在进程正常终止以后, 也会自动关闭. closelog可以在应用进程不再需要发送日志消息时调用, 以关闭与syslogd通信的描述符.

    • 参数
      options 调用openlog时, 通常不立即创建Unixo Domain socket, 而该socket到首次调用syslog时才打开. openlog的options能影响log的行为, 如指定LOG_NDELAY选项将迫使该socket在openlog调用后立即创建, 而不是到调用syslog时才创建.
      openlog的options由一个或多个常值的构成(逻辑或):
    options 说明
    LOG_CONS 若无法发送到syslogd守护进程则登记到控制台
    LOG_NDELAY 不延迟打开, 立即创建套接字
    LOG_PERROR 既发送到syslogd守护进程, 又登记到标准错误输出
    LOG_PID 随每个日志消息登记进程ID

    facility 设施, 标识消息发送进程的类型, 来自不同设施的消息将以不同的方式进行处理. openlog的facility参数, 为没有指定设施的后续syslog调用指定一个默认值, i.e. openlog如果指定了facility, syslog可不必另外指定facility.

    facility XSI 说明
    LOG_AUDIT 审计设施
    LOG_AUTH 授权程序: login, su, getty等
    LOG_AUTHPRIV 与LOG_AUTH相同, 但写日志文件时具有权限限制
    LOG_CONSOLE 消息写入 /dev/console
    LOG_CRON cron和at
    LOG_DAEMON 系统守护进程: inetd, routed等
    LOG_FTP FTP守护进程(ftpd)
    LOG_KERN 内核产生的消息
    LOG_LOCAL0 保留本地使用
    LOG_LOCAL1 保留本地使用
    LOG_LOCAL2 保留本地使用
    LOG_LOCAL3 保留本地使用
    LOG_LOCAL4 保留本地使用
    LOG_LOCAL5 保留本地使用
    LOG_LOCAL6 保留本地使用
    LOG_LOCAL7 保留本地使用
    LOG_LPR 行式打印机系统: lpd, lpc等
    LOG_MAIL 邮件系统
    LOG_NEWS Usenet网络新闻系统
    LOG_NTP 网络时间协议系统
    LOG_SECURITY 安全子系统
    LOG_SYSLOG syslogd守护进程本身
    LOG_USER 来自其他用户进程的消息(默认)
    LOG_UUCP UUCP系统

    3. syslog文件

    3.1 syslog文件存放位置

    Linux下调用syslog函数输出的消息就放在syslog文件, 存放在/var/log/syslog. syslog文件, 通常用于存放应用程序(守护进程)警告信息.
    其他日志存放位置, 详见: linux系统各种日志存储路径和详细介绍 | 博客园

    3.2 手动删除syslog文件

    步骤:

    1. 删除syslog文件
      到/var/log/目录下rm文件
    $ cd /var/log 
    $ rm -f syslog  # 需要root权限
    
    1. 重启syslog服务
    $ service syslog restart
    

    参见: [LINUX]手动清理syslog | CSDN


    4. 例程

    同时向控制台和syslog输出包含PID的进度信息, 1秒钟更新10%, 到100%为止.

    #include <syslog.h>
    #include <unistd.h>
    #include <stdio.h>
    
    /**
     * linux下syslog存放位置 : /var/log/syslog
     */
    int main()
    {
        int i;
        puts("hello");
    
        /* LOG_CONS: 若无法发送到syslogd守护进程则登记到控制台; 
        LOG_PID: 随每个日志消息登记进程PID;
        LOG_PERROR: 既发送到syslogd守护进程,也发送到stderr;
        LOG_USER: 任意的用户级消息(默认) */
        openlog("mysyslog", LOG_CONS | LOG_PID |  LOG_PERROR, LOG_USER);
        syslog(LOG_INFO, "system is starting..." );
        
        for (i = 0; i < 10; ++i) {
            
            syslog(LOG_WARNING | LOG_USER, "process %d
    ", (i + 1) * 10);
            sleep(1);
        }
        
        closelog();
        return 0;
    }
    

    控制台输出结果:

    $ ./a.out 
    hello
    mysyslog[26710]: system is starting...
    mysyslog[26710]: process 10
    mysyslog[26710]: process 20
    mysyslog[26710]: process 30
    mysyslog[26710]: process 40
    mysyslog[26710]: process 50
    mysyslog[26710]: process 60
    mysyslog[26710]: process 70
    mysyslog[26710]: process 80
    mysyslog[26710]: process 90
    mysyslog[26710]: process 100
    

    syslog输出结果:

  • 相关阅读:
    php_package v2.7发布了 宋正河作品
    svn图文教程-宋正河整理
    ci框架学习整理
    php+mysql 数据库分表分段备份程序--宋正河
    保留mysql数据库中的最新1000条记录
    php 文件上传缩略图路径分析类
    php js css加载合并函数 宋正河整理
    二级域名 cookie session 共享
    图像处理相关概念
    由Python到深度学习入门之Keras、TensorFlow 、PyTorch联系与区别
  • 原文地址:https://www.cnblogs.com/fortunely/p/14881448.html
Copyright © 2011-2022 走看看