各位,有没有一种 *nix 解决方案可以让日志文件充当循环缓冲区?例如,我希望日志文件存储最多 1Gb 的数据,并在达到限制后丢弃较旧的条目。
这有可能吗?我认为为了实现这一点,日志文件应该变成某种特殊的设备……
PS 我知道有其他日志轮转工具,但这不是我需要的。日志轮转需要大量 IO,通常每天发生一次,而我需要“运行时”解决方案。
答案1
Linux 有一个内核环形缓冲区。您可以使用dmesg
到显示它。
或者这里是一个Linux内核模块,它可以完成您想要做的事情。
什么是 emlog?
emlog 是一个 Linux 内核模块,它可以轻松访问进程的最新(且仅是最新)输出。它的工作方式与日志文件上的“tail -f”相同,但所需的存储空间永远不会增长。这在嵌入式系统中非常有用,因为嵌入式系统中没有足够的内存或磁盘空间来保存完整的日志文件,但有时需要最新的调试消息(例如,在观察到错误后)。
emlog 内核模块实现了简单的字符设备驱动程序。该驱动程序的作用类似于具有有限循环缓冲区的命名管道。缓冲区的大小很容易配置。随着更多数据写入缓冲区,最旧的数据将被丢弃。从 emlog 设备读取的进程将首先读取现有缓冲区,然后在写入新文本时查看它,类似于使用“tail -f”监视日志文件。(如果进程需要获取日志的当前内容而不阻塞以等待新数据,则还支持非阻塞读取。)
答案2
我能想到的最接近的东西是 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
答案3
您可以使用多日志来自 djb 的 Daemontools。你通过管道输出日志进入是的,这是对数旋转,但旋转很简单:
ln current $tai64nlocaltimestamp
在几乎所有现代 Linux 文件系统上,这都是一项超快的操作。您可以指定需要多少个日志文件以及它们的大小。创建 10 x 1024mb 文件,您将拥有 1gb 环形缓冲区。
请注意,由于自动轮换,每个多日志实例只有一个源。但您可以通过使用 netcat 或手动编写一个简单的包装器来解决此问题。
答案4
有趣的问题;你通常不认为这是一种设计。我确实有一个程序使用一种略微类似的技术来记录历史记录,但它使用二进制格式。“日志文件”有四个部分,全部采用与机器无关的格式:
- 一个标题,其中包含魔数和已使用列表和空闲列表中的(最大)条目数、下一个历史记录条目的序列号、已使用列表中的实际条目数、空闲列表中的实际条目数以及文件的长度(每个为 4 个字节)。
- 使用的列表,每个条目给出一个偏移量和一个长度(每个条目的每个部分为 4 个字节)。
- 空闲列表的每个条目与已使用列表的条目类似。
- 主要数据,每个历史记录由一组连续的字节组成,并以空终止符字节终止。
当分配新记录时,如果空闲列表中有空间,则它会覆盖其中的条目(不一定全部使用 - 在这种情况下,碎片会保留在空闲列表中)。当空闲列表中没有空间时,则会在末尾分配新空间。当旧记录轮换出来时,其空间将移至空闲列表,并与任何相邻的空闲记录合并。它旨在处理 SQL 语句,因此记录可以分布在许多行上。此代码适用于指定数量的记录。它本身不限制文件的大小(尽管这样做并不难)。
主要代码历史代码位于两个文件中,即 history.c 和 history.h,可从程序 SQLCMD 的源代码(我的版本,不是 Microsoft 的;我的版本比 Microsoft 的早十年或更早)获得,可从 International Informix User Group 的软件档案。还有一个历史文件转储程序 (histdump.c) 和一个历史测试程序 (histtest.ec - 它声称是 ESQL/C,但本身实际上是 C 代码;它调用的一个支持函数使用了一些 Informix ESQL/C 库函数)。如果您想在不使用 Informix ESQL/C 的情况下进行实验,请联系我 - 请参阅我的个人资料。要编译 histtest,需要进行一些细微的更改,超出其设计范围,另外还需要一个 makefile。