跳到主要内容

日志

Goose 实现了一套日志机制,可为用户提供查询执行、性能指标、系统事件等详细信息。

基础用法

Goose 日志机制可通过专用函数 enable_logging 启用或关闭。日志存储在名为 goose_logs 的特殊视图中,可像标准表一样查询。

示例:

CALL enable_logging();
-- Run some queries...
SELECT * FROM goose_logs;

关闭日志可执行:

CALL disable_logging();

清空当前日志可执行:

CALL truncate_goose_logs();

日志级别

Goose 支持多种日志级别,用于控制日志详细程度:

  • ERROR:仅记录错误信息
  • WARN:记录警告和错误
  • INFO:记录一般信息、警告和错误(默认)
  • DEBUG:记录详细调试信息
  • TRACE:记录非常详细的追踪信息

可通过如下方式设置日志级别:

CALL enable_logging(level = 'debug');

日志类型

在 Goose 中,日志消息可关联日志类型。日志类型主要提供两项能力:

  • 对日志生成进行细粒度控制
  • 支持结构化日志

按类型记录日志

若只记录某一类型日志:

CALL enable_logging('HTTP');

上述函数会自动设置合适的日志级别,并将 HTTP 加入 enabled_log_types 配置,从而确保仅写入 HTTP 类型日志。

若要启用多个日志类型,直接传入:

CALL enable_logging(['HTTP', 'QueryLog']);

结构化日志

部分日志类型(如 HTTP)带有对应消息 schema。要让 Goose 自动解析消息,可使用 goose_logs_parsed() 宏。例如:

SELECT request.headers FROM goose_logs_parsed('HTTP');

若要查看某个结构化日志类型的 schema,可执行:

DESCRIBE FROM goose_logs_parsed('HTTP');

可用日志类型列表

下面是 Goose 中可用日志类型的(非完整)列表。

日志类型说明是否结构化
QueryLog记录 Goose 中执行了哪些查询
FileSystem记录 Goose 文件系统相关的所有交互
HTTP记录 Goose 内部 HTTP 客户端的所有 HTTP 流量

日志存储

默认情况下,Goose 将日志写入内存日志存储(memory)。Goose 支持不同日志存储类型,目前 core Goose 中实现了以下类型:

日志存储说明
memory(默认)写入内存缓冲区
stdout写入当前进程的 stdout(CSV 格式)
file写入一个或多个 csv 文件

注意:goose_logs 视图会自动指向当前激活的日志存储。因此切换日志存储后,goose_logs 返回结果可能变化。

输出到 stdout

CALL enable_logging(storage = 'stdout');

输出到文件

CALL enable_logging(storage = 'file', storage_config = {'path': 'path/to/store/logs'});

或使用等价简写:

CALL enable_logging(storage_path = 'path/to/store/logs');

高级用法

规范化与非规范化日志

Goose 的日志存储支持两种记录方式:规范化(normalized)与非规范化(denormalized)。

在非规范化日志中,上下文信息会直接附加到每条日志;在规范化日志中,日志条目与上下文分开存储,并通过 context_ids 关联上下文信息。

日志存储是否规范化
memory
file可配置
stdout

对于文件存储,可通过路径是否以 .csv 结尾在规范化与非规范化间切换(.csv 为规范化;非 .csv 为非规范化)。文件日志通常建议使用非规范化,因为性能更高且日志总体积更小。配置 file 日志存储规范化方式如下:

-- normalized: creates `/tmp/goose_log_contexts.csv` and `/tmp/goose_log_entries.csv`
CALL enable_logging(storage_path = '/tmp');
-- denormalized: creates `/tmp/logs.csv`
CALL enable_logging(storage_path = '/tmp/logs.csv');

注意:规范化与非规范化的差异通常会被 goose_logs 函数屏蔽,因为它会自动将规范化表 join 成统一结果。也就是说,上述两种配置都可通过 FROM goose_logs; 查询,并得到一致结果。

缓冲区大小

Goose 日志存储实现了缓冲机制以优化日志性能。该机制会在日志生成与实际写入之间引入潜在延迟。这种延迟会模糊真实写入时点,尤其在排查崩溃时会带来问题,因为崩溃前刚产生的日志可能尚未落盘。可通过如下方式配置缓冲区大小:

CALL enable_logging(storage_config = {'buffer_size': 0});

或使用等价简写:

CALL enable_logging(storage_buffer_size = 0);

注意,不同日志存储的默认缓冲区大小不同:

日志存储默认缓冲区大小
memorySTANDARD_VECTOR_SIZE (2048)
fileSTANDARD_VECTOR_SIZE (2048)
stdout关闭(0)

例如,若要提升 stdout 日志性能,可开启缓冲以显著(>10x)加速日志写入:

CALL enable_logging(storage = 'stdout', storage_buffer_size = 2048);

或者,假设你正在排查 Goose 崩溃并希望用 file 日志器定位问题: 可按如下方式配置缓冲参数:

CALL enable_logging(storage_path = '/tmp/mylogs', storage_buffer_size = 2048);

语法糖

Goose 提供了一些语法糖以简化常见写法。例如,下面语句是等价的:

-- regular invocation 
CALL enable_logging(storage = 'file', storage_config = {'path': 'path/to/store/logs'});
-- using shorthand for common path storage config param
CALL enable_logging(storage = 'file', storage_path = 'path/to/store/logs');
-- omitting `storage = 'file'` -> is implied from presence of `storage_config`
CALL enable_logging(storage_config = {'path': 'path/to/store/logs'});