Linux中的守护进程日志记录

70

我在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内置的框架?

10个回答

104

Unix有一个特殊的日志框架syslog,长期以来一直存在。在您的shell中输入以下内容:

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;
}

4
有趣的是,现在针对Linux这个古老工具的改进正在被提出。详情请见:http://www.h-online.com/open/news/item/Journal-end-of-the-line-for-syslog-1382246.html - Vinko Vrsalovic
2
@opc0de 取决于配置(/etc/syslog.conf 或在较新的系统中 /etc/rsyslog.conf 或包含的内容,/etc/rsyslog.d/*.conf)。您的配置可能位于其他位置,请查阅您系统的手册。 - Vinko Vrsalovic

24

这可能是场马拉松比赛,但是在大多数Unix衍生操作系统中都存在的syslog facility,是首选的日志记录方式。将日志记录到文件中没有什么问题,但是你需要自己承担以下一些任务:

  • 你的日志位置上是否有文件系统以保存文件
  • 如何处理缓冲(以提高性能)和刷新(在系统崩溃之前写入日志)
  • 如果你的守护进程长时间运行,那么如何处理不断增长的日志文件。

Syslog会替你处理所有这些问题,甚至更多。其API类似于printf系列函数,所以你应该可以轻松适应你的代码。


12

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

将所有服务器农场的日志放在一个地方比在每台机器上分别阅读要方便得多,特别是当您试图将一个服务器上的事件与另一个服务器上的事件相关联时。 当其中一个被破解时,您就不能再信任它的日志... 但如果日志服务器保持安全,您就知道没有任何日志被删除,因此入侵的任何记录都将完好无损。


8

2

如上所述,您应该研究syslog。但是,如果您想编写自己的日志记录代码,我建议您使用fopen的“a”(写入追加)模式。

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


2

Syslog是一个不错的选择,但您可能希望考虑使用log4c。log4[something]框架在其Java和Perl实现中表现良好,并允许您从配置文件中选择将日志记录到syslog、控制台、平面文件或用户定义的日志编写器。您可以为每个模块定义特定的日志上下文,并根据配置定义每个上下文记录的不同级别(跟踪、调试、信息、警告、错误、严重),并通过捕获信号使您的守护进程动态重新读取配置文件,从而允许您在运行的服务器上操作日志级别。


2
如果您使用线程并将日志记录用作调试工具,则需要寻找使用某种线程安全但未锁定的环形缓冲区的日志记录库。每个线程一个缓冲区,在严格需要时才使用全局锁。
这样可以避免日志记录导致软件严重减速,并避免添加调试日志时更改heisenbugs。
如果它具有高速压缩的二进制日志格式,在日志记录期间不浪费时间进行格式操作以及一些很好的日志解析和显示工具,那就更好了。
我想提供一些好的代码参考,但我自己没有。我只是想要一个。 :)

1

我们的嵌入式系统没有syslog,所以我编写的守护进程使用类似于您描述的“a”打开模式将调试信息写入文件。我有一个函数来打开日志文件,输出消息,然后关闭文件(只在发生意外情况时才这样做)。但是,我还必须编写处理日志轮换的代码,就像其他评论者提到的那样,其中包括“tail -c 65536 logfile > logfiletmp && mv logfiletmp logfile”。这很粗糙,也许应该称为“日志前截断”,但它可以防止我们的小型RAM磁盘文件系统被日志文件填满。


0

到目前为止,还没有人提到boost log library,它有一个不错且易于使用的方法来将您的日志消息重定向到文件或syslog sink甚至是Windows事件日志。


Boost是一个C++库。这是C。 - cirrusio

0

有很多潜在的问题:例如,如果磁盘已满,您是否希望您的守护进程失败?此外,每次都会覆盖您的文件。通常使用循环文件,这样您就可以在机器上分配足够的空间来存储文件,但是可以保留足够的历史记录以便于使用而不占用太多空间。

有一些工具可以帮助您,例如log4c。如果您的代码是C ++,则可以考虑Apache项目中的log4cxx(在ubuntu / debian上apt-get install liblog4cxx9-dev),但看起来您正在使用C。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接