0%

日志

日志结构

log-format

static const int kBlockSize = 32768;

// Header is checksum (4 bytes), length (2 bytes), type (1 byte).

static const int kHeaderSize = 4 + 2 + 1

日志写入流程

  1. 初始化写入器
    调用 Next 函数获取 singleWriter,用于处理单条日志记录的写入。
  2. 分块(Chunk)管理
    • 开始首个 ChunksingleWriter 初始化后,启动第一个 Chunk 的写入。
    • 数据缓冲:将日志记录数据按顺序写入内存缓冲区。
    • 缓冲区阈值检测:持续监测缓冲区大小,当数据部分(不含 Header)达到 32 KiB - 7 字节(预留 7 字节 Header 空间)时,触发分块操作。
  3. 构建并写入 Chunk
    • 生成 Header:为当前 Chunk 计算校验和,并确定类型(如跨块时的 First/Middle,或结尾的 Last)。
    • 完整 Chunk 写入:将 Header(7 字节) + 数据(≤32 KiB -7 字节) 组合成完整 Chunk,一次性写入日志文件。
    • 重置缓冲区:清空当前缓冲区,准备接收后续数据。
  4. 循环处理与结束标记
    • 重复上述过程,直至日志记录所有数据写入完成。
    • 最后一个 Chunk 标记为 Last 类型,表示记录结束。若数据恰好填满 Chunk,则前一个 Chunk 标记为 Last

日志读取流程

  1. 按块读取数据
    每次从日志文件读取 32 KiB 的 Block,作为基础处理单元。
  2. 初始化读取器
    调用 Next 函数获取 singleReader,用于逐条解析日志记录。
  3. 解析 Chunk
    • 读取 Header:从 Block 头部提取 校验和、数据长度、类型(如 Full/First/Middle/Last)。
    • 数据提取:根据 Header 中的数据长度,从 Block 中读取对应字节的数据内容。
  4. 校验与错误处理
    • 校验和验证:计算数据部分的校验和,与 Header 中的值比对。
    • 错误处理
      • 校验失败:若用户启用严格模式,返回错误;否则丢弃当前 Chunk,继续读取后续 Block。
      • 校验成功:保留数据,准备拼接。
  5. 数据拼接与终止条件
    • 中间 Chunk:若类型为 FirstMiddle,将数据暂存,继续读取下一 Block。
    • 终止 Chunk:遇到 Last 类型时,将当前 Chunk 数据与前序数据合并,返回完整日志记录。