将日志文件变成一种循环缓冲区


22

人们,有没有* nix解决方案可以使日志文件充当循环缓冲区?例如,我希望日志文件最多存储1Gb数据,并在达到限制后丢弃较旧的条目。

有可能吗?我相信为了实现将日志文件转换为某种特殊设备的目的...

PS我知道其他logrotating工具,但这不是我所需要的。对数旋转需要大量的IO,通常一天一次,而我需要一个“运行时”解决方案。


3
我不确定为什么您认为日志轮换需要大量的IO。轮流10个日志文件是10个重命名操作和服务的HUP。不完全是一项具有杀伤力的行动……这是您问题的标准解决方案:)
pehrs

2
可能正在运行的脚本/可执行文件不能很好地与HUP一起使用。
斯科特,

1
这是为您的问题提供另一个用例。我有一个妖魔的音乐播放器。我想要一个长度只有几行的日志,这样我可以看到正在播放的内容以及在此之前播放的内容。一个tail -f somefile会做到这一点。我只是尝试过旋转日志,tail -f但不适用于这些日志。
Vorac

Answers:


14

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

或者是一个Linux内核模块,看起来可以满足您的要求。

什么是emlog?

emlog是一个Linux内核模块,可轻松访问进程的最新(且仅最新)输出。它的工作方式与日志文件上的“ tail -f”相同,所不同的是所需的存储空间永远不会增长。这在没有足够内存或磁盘空间来保存完整日志文件的嵌入式系统中很有用,但是有时需要最新的调试消息(例如,在观察到错误之后)。

emlog内核模块实现了简单的字符设备驱动程序。驱动程序的作用类似于具有有限的圆形缓冲区的命名管道。缓冲区的大小易于配置。随着更多数据写入缓冲区,最早的数据将被丢弃。从emlog设备读取的进程将首先读取现有缓冲区,然后在写入时查看新文本,类似于使用“ tail -f”监视日志文件。(如果进程需要获取日志的当前内容而又不等待新数据的阻塞,则也支持非阻塞读取。)


1
感谢您的链接!顺便说一句,emlog主页上有一个指向ulogbufd的链接,这也许对我来说是一个更合适的解决方案。
pachanga

现在,emlog内核模块已保存在github:github.com/nicupavel/emlog
dbernard

4

我能想到的最接近的东西是RRDTools,但可能不是您正在寻找的东西。另一个解决方案是监视日志文件(例如每秒或在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

+1代表RRDtool,这是环形数据结构记录的真实示例。
科里(Cory J)2010年

感谢您显示inotifywait shell命令用法的示例
pachanga 2010年

4

您可以使用djb的Daemontools中的multilog。您将日志输出通过管道传输其中。是的,它是对数旋转,但是旋转很简单:

ln current $tai64nlocaltimestamp

在几乎任何现代linux文件系统上,这都是超快速的操作。您可以指定所需的日志文件数量,所需的大小。制作10 x 1024mb文件,您将拥有1gb环形缓冲区。

注意,由于自动轮换,每个multilog实例只有一个来源。但是您可以通过使用netcat或手动编写一个简单的包装程序来解决此问题。


谢谢你的提示!我也肯定会同时使用multilog。
pachanga

1

您可以制作一个FIFO管道,然后使用插入数据库的脚本从该管道读取它。当计数器达到1,000时,重新启动要插入数据库的ID号。当然,这不适用于大小,但是您以它为例,所以我假设这是一个理论问题。


1

有趣的问题;您通常不会将其视为设计。我确实有一个使用微弱相似的技术来记录历史的程序,但是它使用的是二进制格式。“日志文件”包含四个部分,所有部分均以机器中立的格式布置:

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

分配新记录时,如果空闲列表中有空间,则它将覆盖那里的条目(不一定要全部使用-在这种情况下,片段保留在空闲列表中)。如果空闲列表中没有空间,则在末尾分配新的空间。当旧记录轮换时,其空间将移至空闲列表,并与任何相邻的空闲记录合并。它旨在处理SQL语句,因此记录可以分布在多行中。此代码适用于指定数量的记录。它本身并不限制文件的大小(尽管这样做并不难)。

主要的代码历史记录代码位于两个文件中,history.c和history.h,可从源代码中获得该程序SQLCMD(我的版本,不是Microsoft的版本;我的版本早于Microsoft的版本已经存在了十年或更长时间),可以从以下位置下载国际Informix用户组的软件档案库。还有一个历史文件转储程序(histdump.c)和一个历史测试器(histt​​est.ec-它声称是ESQL / C,但它本身实际上是C代码;它调用的支持功能之一使用某些Informix ESQL / C库函数)。如果您想不使用Informix ESQL / C进行试验,请与我联系-请参阅我的个人资料。要使其在其设计环境之外编译histt​​est,需要进行一些琐碎的更改,此外还需要一个makefile。


0

我同意佩尔斯对您的问题的评论。日志轮转并不难。您可以设置logrotate或其他脚本来定期检查日志文件,即使您愿意,也可以每分钟检查一次。当它检测到文件大小达到1GB时,它仅执行重命名,几乎不需要I / O。在重命名过程中,该过程将继续写入日志文件。然后,日志循环程序可以将HUP发送到您的syslog守护程序(您的守护程序正在通过syslog进行记录,对吗?如果没有,如果它写的很好,它应该支持HUP信号...)以使其重新打开原始文件路径。此时,它将开始在原始路径上写入新文件,并且您可以删除旋转的版本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.