在Linux中守护进程日志logging
所以我有一个运行在Linux系统上的守护进程,我想logging下它的活动:日志。 问题是,什么是“最好”的方式来完成这个?
我的第一个想法是简单地打开一个文件并写入。
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);
采用这种方式logging有什么天生的错误吗? 有没有更好的方法,比如一些内置于Linux的框架?
Unix已经有了一个特殊的日志框架叫syslog 。 input你的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; }
这可能是一场比赛,但是,如果不是所有的Un * x衍生物,存在于大多数系统日志工具是首选的方式。 login到文件没有任何问题,但它确实使您的肩膀上承担了一些任务:
- 在日志logging位置是否有文件系统来保存文件
- 如何缓冲(性能)vs刷新(获取系统崩溃之前写入的日志)
- 如果守护进程运行了很长时间,那么对于不断增长的日志文件,你会做什么?
系统日志为您处理所有这些,以及更多。 这个API与printf族相似,所以你应该没有任何问题适应你的代码。
系统日志在更大(或更安全意识)的安装中的另一个优点是:系统日志守护进程可以configuration为将日志发送到另一台服务器,而不是(或除了)本地文件系统。
将服务器场的所有日志放在一个地方,而不是在每台机器上分别读取它们,尤其是当您试图将一台服务器上的事件与另一台服务器上的事件关联起来时,这样做更为方便。 当一个人被破解时,你不能相信它的日志了,但是如果日志服务器保持安全,你就知道什么东西都不会从日志中删除,所以任何入侵logging都是完整的。
我在unit testing时向daemon.info和daemon.debug吐出了很多守护进程的消息。 你的syslog.conf中的一行可以将这些消息粘贴到你想要的任何文件中。
系统日志是一个不错的select,但是你不妨考虑看看log4c。 log4 [something]框架在其Java和Perl实现中运行良好,并允许您从configuration文件中selectlogin到syslog,控制台,平面文件或用户定义的日志编写器。 您可以为每个模块定义特定的日志上下文,并根据您的configuration定义不同的日志级别。 (跟踪,debugging,信息,警告,错误,关键),并让守护进程通过捕获信号来重新读取configuration文件,从而允许您在正在运行的服务器上操作日志级别。
如上所述,您应该查看syslog。 但是如果你想写自己的日志代码,我build议你使用fopen的“a”(写入附加)模式。
编写自己的日志代码的一些缺点是:日志循环处理,locking(如果你有多个线程),同步(你是否想等待日志被写入磁盘? 系统日志的一个缺点是应用程序不知道日志是否写入磁盘(它们可能已经丢失)。
如果使用线程,并且使用日志logging作为debugging工具,则需要查找使用某种线程安全但未locking的环形缓冲区的日志logging库。 每个线程一个缓冲区,只有在严格需要时才有全局locking。
这样可以避免日志造成软件严重下滑,避免在添加debugging日志时创build更改的heisenbugs。
如果它有一个高速的压缩二进制日志格式,不会浪费时间在日志logging和一些不错的日志分析和显示工具格式化操作,这是一个奖金。
我提供了一些很好的代码的参考,但我自己没有。 我只想要一个。 🙂
我们的embedded式系统没有系统日志,所以我写的守护进程使用类似于你所描述的“a”打开模式来debugging文件。 我有一个函数,打开一个日志文件,吐出消息,然后closures文件(我只有这样做时,意外的事情发生)。 但是,我还必须编写代码来处理日志轮转,正如其他评论者所提到的那样,它由'tail -c 65536 logfile> logfiletmp && mv logfiletmp logfile'组成。 这是相当粗糙的,也许应该被称为“日志正面截断”,但它阻止我们的小型RAM磁盘的文件系统填满日志文件。
到目前为止,没有人提到boost日志库 ,它有很好很容易的方式来redirect你的日志消息到文件或系统日志接收器甚至Windows事件日志。
有很多潜在的问题:例如,如果磁盘已满,您是否希望守护进程失败? 另外,你每次都会覆盖你的文件。 通常会使用一个循环文件,以便在文件上为计算机分配空间,但是可以保留足够的历史logging而不占用太多空间。 有像log4c这样的工具,你可以帮助你。 如果你的代码是c ++,那么你可能会考虑Apache项目中的log4cxx(apt-get install ubuntu / debian上的liblog4cxx9-dev),但看起来你正在使用C.