具有预分配内存的日志模块

时间:2017-02-10 21:59:12

标签: logging data-structures compression buffer-overflow text-compression

我正在编写一个日志记录机制,其余代码将使用该日志记录机制将字母数字数据记录到文件中。系统中的每个其他模块将发送字母数字句子(最多几个字)以连续写入文件。问题是,我只获得了少量预先分配的内存,用于我的数据结构和这些日志消息的内存存储。如果流入的数量多于可写入磁盘的数量,则会丢弃日志消息。

我想在我的日志模块中的客户端和内存存储之间加入一种压缩机制,这样我就可以保存尽可能多的消息。

到目前为止我目前的设计:

客户------> LOG MODULE ----> 压缩并存储在内存缓冲区1

作家帖子:     当写入时,用缓冲区2切换缓冲区1并将缓冲区1写入文件。在此期间,客户端将写入缓冲区2。

之外的脚本: 解压缩并显示日志消息

问题:     我可以使用什么样的字母数字压缩算法或者我可以用来捕获尽可能多的数据的良好数据结构(在上面的压缩阶段)?

如果可能的话,我想要一种不在中间数据结构中存储压缩代码的算法 - 即,如果系统崩溃,我希望能够解压缩到目前为止写入文件的任何内容。 / p>

到目前为止尝试:     为我们将要使用的每个字符分配一个代码。看起来不那么灵活。

大多数日志消息都是简单的文本句子

1 个答案:

答案 0 :(得分:1)

  

问题:我可以使用什么样的字母数字压缩算法,或者我可以用来捕获尽可能多的数据(在上面的压缩阶段)?

一般来说,算法越慢,内存越多,压缩率越高。不同的编解码器会做出不同的权衡,即使在某些编解码器中,您也可以调整不同的参数以产生不同的权衡。

编解码器对于不同的数据也往往表现得非常不同。有几个基准浮动,但这只会让你对性能有一个大概的了解;要真正选择最适合你的用你的数据并进行自己的测量。

至于在进程崩溃时避免数据丢失,使用当前设计所需的是支持刷新的流式编解码器。每次完成记录消息时,您都希望告诉编解码器进行刷新。这个API将取决于编解码器,但通常你会得到像

这样的东西
foo_compress(stream, output, input);
foo_flush(stream);
fwrite(stream->output, 1, stream->output_size, file);
fflush(stream);

一些库提供了用于读取/写入磁盘的API(允许您跳过fwrite / fflush)。想到壁球,gzip和lzham,但可能还有其他人。但是,在大多数情况下,库只是压缩到缓冲区,并且您负责将缓冲区写入文件。

这里的主要障碍是很多算法都不支持刷新。在我的头顶,gzip,lzham,brotli,bzip2,lzma,zstd和我认为 lz4f支持刷新。如果你做了大量的刷新,bzip2可能不会表现得很好,如果这是一个新系统,那么使用gzip或lzma可能没有多大理由(zstd优于gzip,而brotli和lzham优于lzma在几乎所有方面)。

也就是说,如果您只是为了避免因 代码中的崩溃而导致数据丢失(即,您希望在程序崩溃时保留数据,但您不是太担心操作系统崩溃了),您可能需要考虑将压缩和I / O代码拆分为单独的进程。此时,您最终会得到类似于syslog的内容,或者更新的结构化日志记录API,例如journaldASL或令人惊讶的令人不快的Windows Event Log API。

相关问题