Linux中的守护程序日志记录

时间:2020-03-06 14:59:04  来源:igfitidea点击:

因此,我有一个在Linux系统上运行的守护程序,并且我想要记录其活动:日志。问题是,完成此任务的"最佳"方法是什么?

我的第一个想法是简单地打开一个文件并将其写入。

FILE* log = fopen("logfile.log", "w");
/* daemon works...needs to write to log */
fprintf(log, "foo%s\n", (char*)bar);
/* ...all done, close the file */
fclose(log);

用这种方式记录日志有天生的错误吗?有没有更好的方法,例如Linux内置的某些框架?

解决方案

Unix已经有很长一段时间专门用于syslog的日志记录框架了。输入外壳

man 3 syslog

我们将获得有关它的C接口的帮助。

一些例子

#include <stdio.h>
#include <unistd.h>
#include <syslog.h>

int main(void) {

 openlog("slog", LOG_PID|LOG_CONS, LOG_USER);
 syslog(LOG_INFO, "A different kind of Hello world ... ");
 closelog();

 return 0;
}

存在很多潜在的问题:例如,如果磁盘已满,我们是否希望守护程序失败?另外,我们每次都将覆盖文件。通常,使用循环文件,以便在计算机上为文件分配空间,但是可以保留足够的历史记录以供使用,而不会占用太多空间。
有诸如log4c之类的工具可以为我们提供帮助。如果代码是c ++,则可以考虑在Apache项目中使用log4cxx(在ubuntu / debian上apt-get install liblog4cxx9-dev),但看起来我们正在使用C。

这可能将是一场激烈的竞赛,但是是的,大多数(如果不是全部)Un * x派生词中都存在syslog工具,这是首选方法。记录到文件并没有错,但是它确实让我们承担了许多任务:

  • 日志记录位置是否有文件系统来保存文件
  • 缓冲(性能)与刷新(在系统崩溃之前写入日志)怎么样?
  • 如果守护程序运行了很长时间,我们将如何处理不断增长的日志文件。

Syslog会为我们处理所有这一切,甚至更多。该API与printf家族相似,因此我们在修改代码时应该没有问题。

在进行单元测试时,我向daemon.info和daemon.debug吐出了很多守护程序消息。 syslog.conf中的一行可以将这些消息粘贴到所需的任何文件中。

与手册页imo相比,http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/040/4036/4036s1.html对C API的解释更好。

如上所述,我们应该查看syslog。但是,如果我们想编写自己的日志记录代码,建议我们使用fopen的" a"(写添加)模式。

编写自己的日志代码的一些缺点是:日志轮转处理,锁定(如果有多个线程),同步(是否要等待日志写入磁盘?)。 syslog的缺点之一是应用程序不知道日志是否已写入磁盘(它们可能已经丢失)。

Syslog是一个不错的选择,但是我们不妨考虑查看log4c。 log4 [something]框架在其Java和Perl实现中运行良好,并且允许我们从配置文件中选择登录到syslog,控制台,平面文件或者用户定义的日志编写器。我们可以为每个模块定义特定的日志上下文,并使每个上下文日志处于配置定义的不同级别。 (跟踪,调试,信息,警告,错误,关键),并通过捕获信号让守护进程即时读取该配置文件,从而允许我们在运行的服务器上操纵日志级别。

在较大(或者更注重安全性)的安装中,syslog的另一个优点是:syslog守护程序可以配置为将日志发送到另一台服务器进行记录,而不是(或者除了本地)文件系统。

将服务器场中的所有日志都放在一个位置,而不是必须在每台计算机上分别读取它们,更为方便,尤其是当我们尝试将一台服务器上的事件与另一台服务器上的事件相关联时。而且,当一个人被破解时,我们将无法再信任它的日志了……但是,如果日志服务器保持安全,我们将知道不会从其日志中删除任何内容,因此任何入侵记录都将保持完整。

如果使用线程并将日志记录用作调试工具,则需要查找使用某种线程安全但未锁定的环形缓冲区的日志记录库。每个线程一个缓冲区,仅在严格需要时才使用全局锁。

这样可以避免日志记录导致软件严重减速,并且避免创建在添加调试日志记录时会发生变化的heisenbug。

如果它具有高速压缩的二进制日志格式,并且在日志记录期间不浪费时间进行格式操作,并且提供了一些不错的日志解析和显示工具,那么这将是一个好处。

为此,我将提供一些好的代码的参考,但我自己没有。我只想要一个。 :)

我们的嵌入式系统没有syslog,因此我编写的守护程序使用类似于我们描述过的" a"打开模式对文件进行调试。我有一个打开日志文件,吐出消息然后关闭文件的功能(我仅在发生意外情况时才这样做)。但是,我也不得不编写代码来处理日志轮换,正如其他评论者所提到的那样,它由" tail -c 65536 logfile> logfiletmp && mv logfiletmp logfile"组成。这很粗糙,也许应该称为"日志前端截断",但是它阻止了基于小型RAM磁盘的文件系统填充日志文件。