为什么大多数日志文件使用纯文本而不是二进制格式?


81

日志记录是必需的,但(相对)很少使用。这样,就存储而言可以使其更加紧凑。

例如,最常记录的数据(例如ip,日期,时间)以及其他可以表示为整数的数据将存储为文本。

如果将日志记录存储为二进制数据,则可以保留很多空间,从而需要较少的旋转并增加磁盘寿命,尤其是对于写受到限制的SSD。

有人可能说这是一个很小的问题,实际上并不重要,但是考虑到建立这种机制所需的努力,这是没有道理的。任何人都可以在业余时间里做两天左右的工作,为什么人们不这样做呢?


20
我会挑战您关于人们这样做的主张。很多。当然不能,但是很多可以。
2013年


44
>如果将日志记录存储为二进制数据,则可以保留很多空间。嗯,通常会压缩旧日志。
leonbloy

89
在需要中途中断的机器上读取文本日志可能比需要二进制文件对其进行分析具有巨大优势。
tofro

23
经过几个月的修改以使算法在大型集群上正确执行,我们仍然看不到性能的提高,但是当我们改为将日志文件存储在二进制文件中时呢?神圣的牛,我们从来不敢梦想性能可以达到那个水平。这种故事有多合理?
空值

Answers:


163

systemd著名地以二进制格式存储其日志文件。我听到的主要问题是:

  1. 如果日志损坏,则由于需要专业工具而很难恢复
  2. 他们不是人类可读的,所以你不能使用标准工具,如vigreptail等来分析它们

使用二进制格式(据我所知)的主要原因是,创建索引等(即将其更像数据库文件一样)被认为更容易。

我认为磁盘空间优势在实践中相对较小(并且在逐渐减少)。如果您要存储大量日志,则压缩滚动日志确实非常有效。

总而言之,在大多数情况下,工具和熟悉性的优势可能会在文本记录方面出现。


3
好点子。我也立刻想到了systemd。这里更重要的部分是您的应用程序不必知道日志数据的存储方式。它可以作为系统服务提供。
5gon12eder

97
“著名”,更像是“臭名昭著”
whatsisname

4
PF(防火墙)也记录在二进制的,具体地,涉及tcpdump的格式
尼尔圭根

3
@Hatshepsut滚动日志:日志输出写入一个文件,例如myapp.log直到午夜,然后将该文件移至myapp.log.1,然后开始写入新myapp.log文件。而旧的myapp.log.1被转移到myapp.log.2,依此类推,他们全都沿着。因此,myapp.log永远是当前的。或者当达到一定大小时它们可能会切换。也许他们将日期/时间放在文件名中。许多日志记录框架开箱即用地支持这种事情。
SusanW

13
@Hatshepsut据rotating我所知,该术语也被使用。
乔治D

89

为什么大多数日志文件使用纯文本而不是二进制格式?

Unix哲学 Wikipedia文章中搜索“文本”一词,例如,您将找到以下语句:

麦克尔罗伊(McIlroy),当时是贝尔实验室CSRC(计算机科学研究中心)的负责人,也是Unix管道的发明者,[9]总结了Unix哲学,内容如下:[10]

这是Unix的哲学:编写可以做一件事并且做得很好的程序。编写程序以协同工作。编写程序来处理文本流,因为这是一个通用接口。

或者例如,从Unix哲学基础

组成规则:设计要与其他程序连接的程序。

如果您的程序都无法相互通信,则很难避免编写过于复杂的整体。

Unix的传统强烈鼓励编写可读写简单,文本,面向流,与设备无关的格式的程序。在经典的Unix下,将尽可能多的程序编写为简单过滤器,这些过滤器在输入时采用一个简单的文本流,然后在输出时将其处理为另一个简单的文本流。

尽管有流行的神话,但这种做法不受青睐,因为Unix程序员讨厌图形用户界面。这是因为,如果您不编写接受和发出简单文本流的程序,则将这些程序挂在一起要困难得多。

文本流适用于Unix工具,而消息适用于面向对象设置中的对象。文本流界面的简单性增强了工具的封装。诸如远程过程调用之类的更为复杂的进程间通信形式,表现出一种趋势,即彼此之间内部程序的参与过多。

任何人都可以在业余时间里做两天左右的工作,为什么人们不这样做呢?

以二进制格式存储日志文件仅仅是开始(而且微不足道)。然后,您需要编写工具来:

  • 显示整个日志文件(edit
  • 显示日志的结尾,而不读取日志的开头(tail -f
  • 在文件(grep)中搜索内容
  • 过滤器仅显示选定的/有趣的东西(使用任意复杂的过滤器表达式)
  • 通过电子邮件将日志发送给没有您的日志文件解码器软件的其他人
  • 复制并粘贴日志文件的一部分
  • 在仍在开发和调试程序(创建日志文件)的同时读取日志文件
  • 从软件的旧版本读取日志文件(已部署在客户站点上并正在运行)。

显然,软件也可以并且确实也使用二进制文件格式(例如,用于关系数据库),但是对于日志文件,它不值得(在YAGNI的意义上),通常不值得这样做。


24
不要忘记文档!几年前,我为系统编写了一个二进制消息记录器,该记录器记录了传入请求以进行回归/重播。现在,了解这些糟糕文件的唯一方法是查看读取/写入它们的代码,而其他团队则使用它们并提出有关它们的问题。可怕的事情。
SusanW

2
公平地说,将您的日志存储在SQLite数据库中并与用于读取的基本查询工具结合使用,将提供您开箱即用提及的所有功能。;)
jpmc26

3
@ jpmc26是的,只要您可以读取日志文件,就可以将其转换为文本格式...
ChrisW

1
如其他评论所述:文本文件可以轻松高效地压缩。但是压缩不需要在“数据”中。压缩可以在文件系统中完成。因此,您可以对所有工具使用纯文本格式,而不会浪费磁盘空间。
Bernd Wilkeπφ16年

2
@杰夫·N 如果我tail -f在多GB的日志文件上运行,它将跳到文件末尾(使用“ seek”而不是“ read”),然后仅读取并显示文件的末尾。它不需要解压缩/解码整个文件。
ChrisW

49

这里有很多值得商de的假设。

日志记录一直是我几乎每一项工作的组成部分。如果您希望对应用程序的运行状况有任何可见性,这是​​至关重要的。我怀疑这是“附带”用途;我参与过的大多数组织都认为日志非常重要。

将日志存储为二进制意味着您必须先对其进行解码,然后才能读取它们。文本日志具有简单易用的优点。如果您打算使用二进制路由,则最好将日志存储在数据库中,在其中可以查询日志并进行统计分析。

如今,SSD比HDD更加可靠,而且反对大量写入的争论在很大程度上还没有定论。如果您真的很担心,可以将日志存储在普通硬盘上。


19
“您最好将日志存储在数据库中,您可以在其中查询日志并进行统计分析。” 在上一份工作中,我们有一个自定义工具,正是出于这个目的,该工具将我们(基于文本的)日志导入数据库中。
梅森惠勒

5
我很难理解OP的“写入受限的SSD”的意思是,SSD中的写入/擦除周期有限,并且在某个扇区上写入过多会缩短设备的使用寿命。她并不是说写就丢了。
图兰斯·科尔多瓦

4
@TulainsCórdova:是的,我知道她的意思。
罗伯特·哈维

2
@DocSalvager:我没有断言。
罗伯特·哈维

2
@TulainsCórdova - SSD的写入周期的限制通常是非常高的,这些天。即使是低成本的消费级SSD也有制造商保证,其写入周期可能高达设备尺寸的数百倍,而MTBF可以覆盖您写入设备容量数千倍的情况。而且在商业环境中,您应该使用具有更大写入周期限制的高端设备,并且至少应在5年的周期内对其进行更换,因此除非您每天写入的存储容量> 10%,否则我认为不用担心
Jules

36

日志文件是任何重要应用程序的重要组成部分:如果应用程序中的日志记录很好,则它们可以让您查看发生了哪些关键事件以及何时发生;发生了什么错误;以及一般应用程序的运行状况,而超出了设计的监视范围。通常会听到问题,检查应用程序的内置诊断程序(打开其Web控制台或使用诊断工具,如JMX),然后诉诸检查日志文件。

如果您使用非文本格式,那么您将立即面临一个障碍:如何读取二进制日志?使用您的生产服务器上没有的日志读取工具!还是这样,但是,亲爱的,我们添加了一个新字段,这是旧的读者。我们没有测试吗?是的,但是没有人在这里部署它。同时,您的屏幕开始亮起,用户对您执行ping操作。

也许这不是您的应用程序,但是您正在提供支持,并且您认为这是另一个系统,并且是WTF?日志是二进制格式?好的,开始阅读Wiki页面,您从哪里开始?现在,我已将它们复制到本地计算机上,但是-它们已损坏?我是否进行了某种非二进制转移?还是日志读取工具搞砸了?

简而言之,文本阅读工具是跨平台的并且无处不在,日志通常是长期存在的,有时需要急着阅读。如果您发明了一种二进制格式,那么您将与一个广为人知且易于使用的工具截然不同。仅在需要时严重丧失功能。

大多数日志记录环境都有一个折衷方案:保持当前日志的可读性和存在性,并压缩较旧的日志。这意味着您将获得压缩的好处-实际上,更重要的是,因为二进制格式不会缩小日志消息。同时,您可以使用lessgrep等。

那么,使用二进制文件可能带来什么好处?少量的空间效率-越来越不重要。更少(或更小的)写?好吧,也许-实际上,写入的数量将与磁盘提交的数量有关,因此,如果日志行远小于磁盘块大小,则SSD会一遍又一遍地分配新的块。因此,在以下情况下,二进制是合适的选择:

  • 您正在编写大量的结构化数据
  • 必须特别快速地创建日志
  • 您不太可能需要在“支持条件”下对其进行分析

但这听起来不像应用程序日志记录;这些是输出文件或活动记录。将它们放在文件中可能距离将它们写入数据库仅一步之遥。

编辑

我认为“程序日志”(根据日志框架)与“记录”(如访问日志,登录记录等)之间存在普遍的混淆。我怀疑这个问题与后者关系最密切,在那种情况下,这个问题的定义远没有那么明确。消息记录或活动日志采用紧凑格式是完全可以接受的,尤其是因为它很可能定义明确并用于分析而非故障排除。执行此操作的工具包括tcpdump和Unix系统监视器sar。另一方面,程序日志往往更临时。


1
甚至Unix /var/log/utmp/ wtmp都是二进制的。他们记录谁当前登录了哪个tty(因此他们不仅仅会增长),但是它们是登录的一种形式。(而且能够便宜地解析它们是有用的,因为各种常用命令都可以这样who做。)
Peter Cordes

1
@PeterCordes非常正确。同样,定义明确的数据。结构化记录。当然,在当时,各种规模的速度和规模都是至关重要的考虑因素。
SusanW

9

二进制日志的一个例子是广泛传播的Windows事件日志。在专业方面,这使日志消息变得非常罗((因此希望有所帮助),几乎免费,可能是类似

警告:在过去90秒钟内,要执行的foobar队列增加了517个项目。如果这种情况每天发生一次,则无需担心。如果它频繁发生或快速连续发生,则可能要检查foobar应用程序可用的RAM量。但是,如果它与事件12345一起发生,则您似乎正在使用一个过时的数据库,最好致电+ 1-555-12345与支持部门联系,以防止数据丢失。

该消息的主要部分作为与应用程序一起安装的资源仅存在一次。但是,如果未正确安装此资源(例如,因为与此同时已经安装了不再支持此过时消息的较新版本),则事件日志中您看到的只是一条标准消息,其措辞不俗

Dunno,用“ 517”和“ 90”表示。

不再有任何帮助。


9
更不用说在Windows事件日志中找到某些内容可能是一场噩梦。这肯定使我渴望一个简单的文本文件。
迈克尔·汉普顿

4
等待。您是否想同时看到两个(或更多)日志条目?太糟糕了。
埃里克大厦

2
我的答案是“ Windows事件日志,足够了”。
Craig

我对事件查看器缺少资源的经验,一直与不工具资源来安装,但在这种情况下,AFAIR,仍然有从该报告程序的实际信息的线,在底部,Windows完成其之后“资源可能已丢失或损坏”高谈阔论。
underscore_d

5

在文本和二进制之间进行选择之前,您要问的两个主要问题是:

  • 我的听众是谁?
  • 我需要传达什么内容?

普遍的看法是,日志消息的收件人是人。这显然不是一个完美的假设,因为那里有许多日志爬网脚本,但这是一个常见的脚本。在这种情况下,有意义的是在人类喜欢的介质中传达信息。文本一直是这种媒体的悠久传统。

至于内容,请考虑二进制日志必须具有定义良好的格式。该格式必须定义得足够好,以便其他人编写可在这些日志上运行的软件。一些日志的结构非常好(您的问题列出了几个)。其他日志需要以定义得不太明确的自然语言形式传达内容的能力。这种自然语言案例与二进制格式的匹配很差。

对于可以用二进制很好地描述的日志,您必须做出选择。由于文本适用于所有人,因此通常将其视为默认选择。如果您以文本形式记录结果,那么人们可以使用您的日志。已经被证明了数千次。二进制文件比较棘手。结果,可能是开发人员输出文本的原因仅仅是因为每个人都知道它的行为。


5

TL; DR:大小并不重要,但使用方便却很重要

首先,虽然比较文本和二进制格式在短期日志存储方面的各自优势是一个重要的问题,但大小实际上并不重要。这有两个原因:

  1. 日志是高度冗余的信息,可以很好地压缩:根据我的经验,看到压缩后的日志文件的大小是原始文件大小的5%或更小并不罕见。因此,使用文本或二进制格式不应对日志的长期存储产生任何可衡量的影响。

  2. 无论我们选择哪种格式,如果我们没有实现“日志文件接收器”来压缩日志文件并将其发送到长期存储平台,则日志将迅速填充服务器磁盘。使用二进制格式可能会减慢此速度,但是即使更改10倍也没有太大关系。

文本与二进制日志格式

Unix系统的承诺是,如果我们学会使用标准的工具集来处理按行结构的文本文件(例如grepsortjoinsedawk),我们将能够使用它们快速组装执行任何工作的原型。我们想要,尽管缓慢而粗糙。一旦原型证明了其有用性,我们就可以选择将其转换为真正设计的软件来获得性能或添加其他有用的功能。至少以我的理解,这是Unix哲学的精髓。

换句话说,如果我们可能需要执行处理和分析,那么到今天我们还不能确定,如果我们不知道应该由谁来执行此分析,等等。那么我们处于应该使用原型和文本格式的阶段。日志可能是最佳的。如果我们需要重复执行一小组公认的处理方法,那么我们应该设计一个常年软件系统来执行此分析,并且日志的二进制或结构化格式(例如关系数据库)很可能是最佳。

(前一段时间,我写了一篇关于此的博客文章。)


4

日志文件为文本格式,因为可以使用任何类型的文本编辑器或通过控制台命令显示内容来轻松读取日志文件。

但是,如果有大量数据,则某些日志文件为二进制格式。例如,我正在使用的产品最多存储15000条记录。为了将记录存储在最少的空间中,它们以二进制形式存储。但是,必须编写一个特殊的应用程序以查看记录或将其转换为可以使用的格式(例如电子表格)。

总之,并非所有日志文件都采用文本格式。文本格式的优点是不需要自定义工具即可查看内容。在有大量数据的地方,文件可能是二进制格式。二进制格式将需要一个(自定义)应用程序来读取数据并以人类可读的格式显示。可以将更多数据打包为二进制格式。是否使用文本格式还是二进制格式取决于数据量和查看内容的便利性。


3

在嵌入式系统中,在运行时我可能没有可用的输出通道,应用程序无法承受日志记录所施加的速度冲击,否则日志记录会改变或掩盖我要记录的效果,我经常采取的措施是将二进制数据填充到数组或环形缓冲区中,然后在测试运行结束时将其printf()对其进行处理,或者将其原始转储并编写解释器以将其打印为可读格式。无论哪种方式,我都想获得可读数据。

在拥有更多资源的系统中,为什么要发明不需要优化的方案?


1
同样,当尝试通过9600波特的串行端口从嵌入式设备实时登录到PC时,通常建议压缩数据或使用二进制格式,以防止溢出。
Mawg

3

日志文件旨在帮助调试问题。通常,硬盘空间比工程时间便宜得多。日志文件使用文本,因为有许多用于处理文本的工具(例如tail -f)。甚至HTTP都使用纯文本(另请参见为什么我们不发送二进制文件而不是HTTP上的文本)。

此外,开发纯文本日志记录系统并验证其是否便宜,如果出错会更容易调试,并且在系统发生故障并破坏部分日志的情况下更容易恢复任何有用的信息。


2
由于它是由其他人提出来的,因此我想指出HTTP / 2(注意!)允许进行二进制,双向,多路复用通信。任何热衷于精英的开发人员都应该去快速地真正学习它,然后问自己为什么不早一点实现它。
肖恩·威尔逊

3

损坏的文本文件仍然可以在损坏的部分周围读取。损坏的二进制文件也许可以恢复,但也可能不是。即使它是可恢复的,也将需要更多的工作。另一个原因是二进制日志记录格式使得在急于创建“临时修订”(又称“所有修订中的最永久性修订”)期间,日志记录解决方案将被使用,而不是可以更快地创建的解决方案。


2

我们依靠单元测试来获得并保持软件的健壮性。(我们的大多数代码无头运行在服务器中;对日志文件进行操作后分析是关键策略。)在我们的实现中,几乎每个类都会进行一些日志记录。我们的单元测试的重要部分是使用在单元测试中使用的“模拟”记录器。单元测试将创建一个模拟记录器,并将其提供给要测试的项目。然后(在有用/适当时)分析记录的内容(尤其是错误和警告)。使用基于文本的日志格式使此操作变得容易得多,其原因与对“真实”日志进行分析的原因大致相同:您可以使用更多可快速使用和适应的工具。


2
尽管其他人对此表示不满,但我想指出的是,这种答案仍然有价值,这表明基于文本的日志甚至在最差的实践水平也可以使您以普通程序员实际上并不关心的方式使用,但是应该。+1
肖恩·威尔逊

感谢您的支持评论。我尝试提供我认为至少对某些人有用的信息。这就是我上SO时想要和期望的。
Art Swri

2

从历史上看,日志是事件的官方,手写和顺序记录。当机器能够记录事件时,这些事件会被写入硬拷贝输出设备(例如电传打字机)中,该设备会产生永久的顺序记录,但只能处理文本,并且偶尔会响起BELL ...


2

在大型机时代,我们使用了一种自定义设计的二进制日志格式。主要原因不是要节省空间,这是因为我们希望通过用新条目覆盖旧条目来使日志占用有限的空间。我们想要做的最后一件事是无法诊断由于磁盘已满而引起的问题(在1980年,磁盘空间的价格为$ 1000 / Mb,因此人们买的东西并没有超出他们的需要)。

现在,我仍然喜欢循环日志文件的想法,如果操作系统提供了这种野兽,我会毫不犹豫地使用它。但是二进制不是一个好主意。当您要解决一个关键问题时,您真的不想浪费时间找到正确的命令来解密日志文件。

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.