将日志文件转换成循环缓冲区

人,有没有一个* nix的解决scheme,这将使日志文件充当循环缓冲区? 例如,我希望日志文件存储最大1Gb的数据,并在达到限制时丢弃较早的条目。

有没有可能? 我相信为了实现一个日志文件应该变成某种特殊的设备…

PS我知道杂项login工具,但这不是我所需要的。 Logrotating需要大量的IO,通常每天发生一次,而我需要一个“运行时”解决scheme。

Linux有一个内核环形缓冲区。 您可以使用dmesg来显示它 。

或者, 这里是一个Linux内核模块,它可以做你想做的事情。

什么是emlog?

emlog是一个Linux内核模块,可以轻松访问进程中最新的(也是最新的)输出。 它的工作原理与日志文件中的“tail -f”一样,只是所需的存储空间不会增长。 在没有足够的内存或磁盘空间来保存完整的日志文件的embedded式系统中,这是非常有用的,但是最近的debugging消息有时是需要的(例如,在观察到错误之后)。

emlog内核模块实现简单的字符设备驱动程序。 驱动程序就像一个有限的循环缓冲区的命名pipe道。 缓冲区的大小很容易configuration。 随着更多数据被写入缓冲区,最旧的数据被丢弃。 从emlog设备读取的进程将首先读取现有的缓冲区,然后在写入新文本时看到它,类似于使用“tail -f”监视日志文件。 (如果进程需要获取日志的当前内容而不阻塞等待新数据,则也支持非阻塞式读取。

我能想到的最接近的是RRDTools,但可能不是你要找的东西。 另一个解决scheme是监视日志文件(比如说每秒钟或在Linux中用inotify),例如你写一个脚本,如:

 while :; do if [[ $(stat -c %s $FILE) -gt 10000 ]]; then # rotate the log fi sleep 1 done 

与inotify:

 while :; do if inotifywait [some options] $FILE; then # check size and rotate the file fi done 

您可以使用djb的Daemontools中的multilog 。 你把你的日志输出input它。 是的,它是日志轮换,但旋转只是:

 ln current $tai64nlocaltimestamp 

其中,几乎任何现代Linux文件系统是一个超级快速的操作。 你可以指定你想要多less个日志文件,你想要多大。 使10个1024MB的文件,你会有你的1GB环形缓冲区。

请注意,由于自动旋转,它是每个多logging实例的一个源。 但是你可以通过用netcat或者手写一个简单的包装来解决这个问题。

您可以创build一个FIFOpipe道,然后从中读取使用插入到数据库的脚本。 当计数器达到1000时,重新启动插入到数据库的ID号。 当然不会适合大小,但是你用这个作为例子,所以我认为这是一个理论问题。

有趣的问题; 你通常不会把这看作是一种devise。 我有一个程序,使用一个微弱的相似的技术来logging历史,但它使用二进制格式。 “日志文件”有四个部分,全部以机器中立格式进行布置:

  1. 包含已使用列表和空闲列表中的幻数和(最大)条目数的标题,下一个历史条目的序列号,已使用列表中的实际条目数,空闲列表中的实际条目数,和文件的长度(每个是4个字节)。
  2. 使用的列表,每个条目给出一个偏移量和一个长度(每个条目的每个部分4个字节)。
  3. 空闲列表,每个条目类似于使用的列表条目。
  4. 主要的数据,每个历史logging由一个连续的由一个空终止符字节终止的字节组成。

当新logging被分配时,如果空闲列表中有空格,那么它将覆盖那里的一个条目(不一定全部使用它 – 在这种情况下,碎片仍然在空闲列表上)。 如果空闲列表中没有空格,则在最后分配新空间。 当旧logging旋出时,其空间被移至空闲列表,并与任何相邻的空闲logging合并。 它被devise来处理SQL语句,因此logging可以分布在很多行上。 此代码适用于指定数量的logging。 它不会限制文件本身的大小(尽pipe这样做并不困难)。

主代码的历史代码有两个文件,history.c和history.h,可以从程序SQLCMD(我的版本,不是微软的;我的存在是微软的十年或更早的版本)的源文件中获得,它们可以从国际Informix用户组的软件档案 。 还有一个历史文件转储程序(histdump.c)和一个历史testing器(histt​​est.ec – 它声称是ESQL / C,但本身就是C代码;它调用的支持函数之一使用了一些Informix ESQL / C库函数)。 如果您想在不使用Informix ESQL / C的情况下进行实验,请联系我 – 请参阅我的configuration文件。 有一些微不足道的变化可以让它在devise环境外编译histt​​est,再加上你需要一个makefile。

我同意pehrs对你的问题的评论。 日志轮换并不困难。 您可以设置logrotate或其他脚本来定期检查您的日志文件,如果您愿意,甚至可以每分钟一次。 当它检测到您的文件达到1GB的大小,它只是执行一个重命名,这将接近没有I / O。 在重命名期间,进程继续写入日志文件。 然后日志轮转器可以发送一个HUP到你的系统日志守护进程(你的守护进程正在通过系统日志进行日志logging,如果没有的话,它应该支持HUP信号,如果它写得很好的话…)重新打开原始文件path。 此时它将开始在原始path上写入新文件,并且可以删除旋转的版本。