系统日志

简介: 系统日志

我们知道守护进程完全脱离终端控制,即守护进程不能将错误信息直接输出到控制终端上。例如, printf() 打印不能显示到终端。因此,该如何通过输出信息对守护进程进行程序调试是一个问题。这里介绍使用 syslog 服务,将程序的出错信息输入系统日志,从而可以直观的看到程序的问题所在。在不同的 Linux 发行版中,系统日志文件路径可能有所不同。例如,可能是 /var/log/syslog


syslogLinux 的系统日志管理服务,通过守护进程 syslogd 来维护。该守护进程在启动时会读取配置文件 /etc/syslog.conf 。该文件决定了不同类型的消息发送到何处。例如,紧急消息可被送到系统管理员并在控制台上显示,而警告信息则可被记录到一个文件中。系统日志文件只能由管理员用户查看。


提示

Ubuntu 20.04 版本中的配置文件为: /etc/rsyslog.conf ,其中又将部分配置拆分到了 /etc/rsyslog.d/ 文件夹下,例如: /etc/rsyslog.d/20-ufw.conf

该机制提供了 3syslog 相关函数, openlog() 函数用于打开系统日志服务的一个连接; syslog() 函数用于向日志文件中写入消息,并可以规定消息的优先级、消息输出格式等; closelog() 函数用于关闭系统日志服务的连接。


#include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);点击复制复制失败已复制


openlog() 函数

openlog() 函数中,参数 ident 表示要向每个消息加入的字符串,通常为程序的名称;参数 option 用来指定 openlog() 函数如何控制消息的标志;参数 facility 用来指定程序发送的消息类型。


option 参数配置如下表所示:

具体参数选项 表示含义
LOG_CONS 如果消息无法发送到系统日志,则直接输出到系统控制终端
LOG_NDELAY 立即打开系统日志服务的连接(通常,直接发送第一条消息时才打开连接)
LOG_PERROR 将消息同时发送到 stderr
LOG_PID 在每条消息中包含进程的 PID


facility 参数配置如下:

具体参数选项 表示含义
LOG_AUTHPRIV 安全/授权消息
LOG_CRON 时间守护进程
LOG_DAEMON 其他系统守护进程
LOG_KERN 内核信息
LOG_LOCAL0~7 保留供本地使用
LOG_LPR 行打印机子系统
LOG_MAIL 邮件子系统
LOG_NEWS 新闻子系统
LOG_SYSLOG syslog 内部产生的信息
LOG_USER 一般使用者等级信息
LOG_UUCP UUCP 子系统


syslog()函数

syslog() 函数中,参数 priority 用来指定消息的等级。参数 format 等同于 printf() 函数,即格式化输出。 priority 参数配置如下所示:

具体参数选项 表示含义
LOG_EMERG 系统无法使用
LOG_ALERT 需要立即采取措施
LOG_CRIT 有重要情况发生
LOG_ERR 有错误发生
LOG_WARNING 有警告发生
LOG_NOTICE 正常情况,但也有重要情况
LOG_INFO 信息消息
LOG_DEBUG 调试消息


示例

下面将Linux守护进程中的示例程序用 syslog 服务进行重写,从而选择将程序出错的调试信息输入系统日志文件,便于追踪错误,如下所示:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <syslog.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
  pid_t pid, sid;
  int i, fd;
  char *buf = "This is a Daemon\n";
  pid = fork(); // 第一步
  if (pid < 0) {
    perror("fork error");
    return -1;
  } else if (pid > 0) {
    exit(0); // 父进程退出
  } else {
    openlog("daemon_syslog", LOG_PID, LOG_DAEMON);
    if ((sid = setsid()) < 0) { // 第二步
      syslog(LOG_ERR, "%s\n", "setsid");
      exit(1);
    }
    if ((sid = chdir("/")) < 0) { // 第三步
      syslog(LOG_ERR, "%s\n", "chdir");
      exit(1);
    }
    umask(0); // 第四步
    for (i = 0; i < getdtablesize(); i++) {
      close(i); // 第五步
    }
    if ((fd = open("/tmp/daemon.log", O_CREAT | O_WRONLY | O_TRUNC, 0600)) < 0) {
      syslog(LOG_ERR, "open");
      return -1;
    }
    syslog(LOG_INFO, "%s\n", "open daemon.log");
    while (1) {
      write(fd, buf, strlen(buf));
      sleep(3);
    }
    close(fd);
    closelog();
  }
  return 0;
}点击复制复制失败已复制


编译并运行,查看 /var/log/syslog 即可看到日志:

$ cat syslog
Oct 11 19:45:03 iric-MS-7B89 daemon_syslog[527770]: open daemon.log
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
Shell Linux C语言
【Shell 命令集合 网络通讯 】Linux 查看系统中的UUCP日志文件 uulog命令 使用指南
【Shell 命令集合 网络通讯 】Linux 查看系统中的UUCP日志文件 uulog命令 使用指南
32 0
|
5月前
|
存储 监控 数据可视化
小白带你学习linux的ELK日志收集系统
小白带你学习linux的ELK日志收集系统
166 0
|
6月前
|
Web App开发 监控 NoSQL
ELK日志分析系统部署文档 1
ELK日志分析系统部署文档
115 0
|
5月前
|
存储 监控 安全
带你读《Apache Doris 案例集》——07查询平均提速700% ,奇安信基于 Apache Doris 升级日志安全分析系统(1)
带你读《Apache Doris 案例集》——07查询平均提速700% ,奇安信基于 Apache Doris 升级日志安全分析系统(1)
179 1
|
5月前
|
SQL 存储 安全
带你读《Apache Doris 案例集》——07查询平均提速700% ,奇安信基于 Apache Doris 升级日志安全分析系统(2)
带你读《Apache Doris 案例集》——07查询平均提速700% ,奇安信基于 Apache Doris 升级日志安全分析系统(2)
209 0
|
22天前
|
JavaScript Java 测试技术
基于Java的公司员工工作日志办公系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的公司员工工作日志办公系统的设计与实现(源码+lw+部署文档+讲解等)
141 3
|
1月前
|
C++
QT实现一个简单的日志打印系统
QT实现一个简单的日志打印系统
|
2月前
|
XML Java 开发者
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之SpringBoot整合众多日志管理系统服务starter-logging
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之SpringBoot整合众多日志管理系统服务starter-logging
37 1
|
3月前
|
调度 数据库 数据安全/隐私保护
ABAP 系统里使用事务码 SM21 查看系统日志的技巧介绍
ABAP 系统里使用事务码 SM21 查看系统日志的技巧介绍
54 0