所以我在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内置的一些框架?
答案 0 :(得分:97)
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;
}
答案 1 :(得分:22)
这个可能是赛马,但是大多数(如果不是全部)Un * x衍生品中存在的syslog工具是首选的方式。记录到文件没有任何问题,但它确实留下了许多任务:
Syslog会为您解决所有这些问题。 API类似于printf部落,因此您在修改代码时应该没有任何问题。
答案 2 :(得分:11)
更大(或更安全意识)安装中syslog的另一个优点:syslog守护程序可以配置为将日志发送到另一台服务器以便在那里进行记录,而不是(或除了)本地文件系统。
将服务器场的所有日志放在一个位置更方便,而不必在每台计算机上单独读取它们,尤其是当您尝试将一台服务器上的事件与另一台服务器上的事件相关联时。当一个人破解时,你不能再信任它的日志......但是如果日志服务器保持安全,你知道什么都不会从它的日志中删除,所以任何入侵记录都将完好无损。
答案 3 :(得分:8)
当我进行单元测试时,我向daemon.info和daemon.debug吐出了很多守护进程消息。 syslog.conf中的一行可以将这些消息粘贴到您想要的任何文件中。
http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/040/4036/4036s1.html比手册页imo。
更好地解释了C API答案 4 :(得分:2)
如上所述,您应该查看syslog。但是如果你想编写自己的日志代码,我建议你使用fopen的“a”(写附加)模式。
编写自己的日志记录代码有一些缺点:日志轮换处理,锁定(如果你有多个线程),同步(你想等待日志写入磁盘吗?)。 syslog的一个缺点是应用程序不知道日志是否已写入磁盘(它们可能已丢失)。
答案 5 :(得分:2)
Syslog是一个不错的选择,但您可能希望考虑查看log4c。 log4 [something]框架在其Java和Perl实现中运行良好,并允许您 - 从配置文件 - 选择登录到syslog,控制台,平面文件或用户定义的日志编写器。您可以为每个模块定义特定的日志上下文,并将每个上下文日志记录在配置定义的不同级别。 (跟踪,调试,信息,警告,错误,严重),并让您的守护进程通过捕获信号来动态重新读取该配置文件,允许您在正在运行的服务器上操作日志级别。
答案 6 :(得分:2)
如果使用线程并使用日志记录作为调试工具,则需要查找使用某种线程安全但未锁定的环形缓冲区的日志库。每个线程一个缓冲区,仅在严格需要时才使用全局锁定。
这样可以避免日志记录导致软件严重减速,并避免在添加调试日志记录时创建更改的heisenbug。
如果它具有高速压缩二进制日志格式,在日志记录期间不会浪费时间格式化操作,而且还有一些不错的日志解析和显示工具,这是一个奖励。
我会为此提供一些好的代码,但我自己没有。我只想要一个。 :)
答案 7 :(得分:1)
我们的嵌入式系统没有syslog,因此我编写的守护进程使用类似于你所描述的“a”打开模式对文件进行调试。我有一个打开日志文件的函数,吐出消息然后关闭文件(我只在意外发生时才这样做)。但是,我还必须编写代码来处理日志轮换,因为其他评论者提到它包含'tail -c 65536 logfile&gt; logfiletmp&amp;&amp; mv logfiletmp logfile'。它非常粗糙,可能应该被称为“日志正面截断”,但它会阻止我们的小型基于RAM磁盘的文件系统填满日志文件。
答案 8 :(得分:1)
到目前为止,还没有人提到boost log library,它有一个很好的方法来重定向你的 将消息记录到文件或syslog sink甚至是Windows事件日志。
答案 9 :(得分:0)
存在许多潜在问题:例如,如果磁盘已满,您是否希望您的守护程序失败?此外,您每次都会覆盖您的文件。通常使用循环文件,以便在机器上为文件分配空间,但是您可以保留足够的历史记录,而不占用太多空间。 有一些像log4c这样的工具,你可以帮助你。如果您的代码是c ++,那么您可以考虑在Apache项目中使用log4cxx(在ubuntu / debian上使用apt-get install liblog4cxx9-dev),但看起来您使用的是C语言。