文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  基于规则的错误日志过滤(log_filter_dragnet)

7.4.2.6 基于规则的错误日志过滤(log_filter_dragnet)

log_filter_dragnet 日志过滤器组件支持基于用户定义规则的日志过滤。

要启用 log_filter_dragnet 过滤器,首先加载过滤器组件,然后修改 log_error_services 值。以下示例启用 log_filter_dragnet 与内置日志接收器结合使用

INSTALL COMPONENT 'file://component_log_filter_dragnet';
SET GLOBAL log_error_services = 'log_filter_dragnet; log_sink_internal';

要设置 log_error_services 以在服务器启动时生效,请使用 第 7.4.2.1 节,“错误日志配置” 中的说明。这些说明也适用于其他错误记录系统变量。

启用 log_filter_dragnet 后,通过设置 dragnet.log_error_filter_rules 系统变量来定义其过滤规则。规则集包含零条或多条规则,每条规则都是一个以句点 (.) 字符结尾的 IF 语句。如果变量值为空(零条规则),则不会进行过滤。

示例 1. 此规则集删除信息事件,并为其他事件删除 source_line 字段

SET GLOBAL dragnet.log_error_filter_rules =
  'IF prio>=INFORMATION THEN drop. IF EXISTS source_line THEN unset source_line.';

效果类似于 log_sink_internal 过滤器设置 log_error_verbosity=2 执行的过滤。

为了可读性,您可能更喜欢将规则列在单独的行上。例如

SET GLOBAL dragnet.log_error_filter_rules = '
  IF prio>=INFORMATION THEN drop.
  IF EXISTS source_line THEN unset source_line.
';

示例 2:此规则将信息事件限制为每 60 秒不超过一次

SET GLOBAL dragnet.log_error_filter_rules =
  'IF prio>=INFORMATION THEN throttle 1/60.';

一旦您按需设置了过滤配置,请考虑使用 SET PERSIST 而不是 SET GLOBAL 来分配 dragnet.log_error_filter_rules,以使设置在服务器重启后持久化。或者,将设置添加到服务器选项文件。

使用 log_filter_dragnet 时,将忽略 log_error_suppression_list

要停止使用过滤语言,首先将其从错误记录组件集中删除。通常这意味着使用不同的过滤器组件而不是没有过滤器组件。例如

SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal';

再次考虑使用 SET PERSIST 而不是 SET GLOBAL 以使设置在服务器重启后持久化。

然后卸载过滤器 log_filter_dragnet 组件

UNINSTALL COMPONENT 'file://component_log_filter_dragnet';

以下部分更详细地描述了 log_filter_dragnet 操作的各个方面

log_filter_dragnet 规则语言语法

以下语法定义了 log_filter_dragnet 过滤器规则的语言。每个规则都是一个以句点 (.) 字符结尾的 IF 语句。该语言不区分大小写。

rule:
    IF condition THEN action
    [ELSEIF condition THEN action] ...
    [ELSE action]
    .

condition: {
    field comparator value
  | [NOT] EXISTS field
  | condition {AND | OR}  condition
}

action: {
    drop
  | throttle {count | count / window_size}
  | set field [:= | =] value
  | unset [field]
}

field: {
    core_field
  | optional_field
  | user_defined_field
}

core_field: {
    time
  | msg
  | prio
  | err_code
  | err_symbol
  | SQL_state
  | subsystem
}

optional_field: {
    OS_errno
  | OS_errmsg
  | label
  | user
  | host
  | thread
  | query_id
  | source_file
  | source_line
  | function
  | component
}

user_defined_field:
    sequence of characters in [a-zA-Z0-9_] class

comparator: {== | != | <> | >= | => | <= | =< | < | >}

value: {
    string_literal
  | integer_literal
  | float_literal
  | error_symbol
  | priority
}

count: integer_literal
window_size: integer_literal

string_literal:
    sequence of characters quoted as '...' or "..."

integer_literal:
    sequence of characters in [0-9] class

float_literal:
    integer_literal[.integer_literal]

error_symbol:
    valid MySQL error symbol such as ER_ACCESS_DENIED_ERROR or ER_STARTUP

priority: {
    ERROR
  | WARNING
  | INFORMATION
}

简单条件将字段与值进行比较或测试字段是否存在。要构建更复杂的条件,请使用 ANDOR 运算符。这两个运算符具有相同的优先级,并从左到右进行评估。

要在字符串中转义字符,请在其前面加上反斜杠 (\)。反斜杠是必需的,用于包含反斜杠本身或字符串引号字符,对于其他字符是可选的。

为了方便起见,log_filter_dragnet 支持对某些字段进行比较的符号名称。为了可读性和可移植性,符号值优先于数值(在适用情况下)。

  • 事件优先级值 1、2 和 3 可以指定为 ERRORWARNINGINFORMATION。优先级符号仅在与 prio 字段进行比较时才被识别。这些比较是等效的

    IF prio == INFORMATION THEN ...
    IF prio == 3 THEN ...
  • 错误代码可以以数字形式指定,也可以作为相应的错误符号指定。例如,ER_STARTUP 是错误 1408 的符号名称,因此这些比较是等效的

    IF err_code == ER_STARTUP THEN ...
    IF err_code == 1408 THEN ...

    错误符号仅在与 err_code 字段和用户定义字段进行比较时才被识别。

    要查找与给定错误代码号对应的错误符号,请使用以下方法之一

    假设包含错误号的规则集如下所示

    IF err_code == 10927 OR err_code == 10914 THEN drop.
    IF err_code == 1131 THEN drop.

    使用 perror,确定错误符号

    $> perror 10927 10914 1131
    MySQL error code MY-010927 (ER_ACCESS_DENIED_FOR_USER_ACCOUNT_LOCKED):
    Access denied for user '%-.48s'@'%-.64s'. Account is locked.
    MySQL error code MY-010914 (ER_ABORTING_USER_CONNECTION):
    Aborted connection %u to db: '%-.192s' user: '%-.48s' host:
    '%-.64s' (%-.64s).
    MySQL error code MY-001131 (ER_PASSWORD_ANONYMOUS_USER):
    You are using MySQL as an anonymous user and anonymous users
    are not allowed to change passwords

    用错误符号替换数字,规则集变为

    IF err_code == ER_ACCESS_DENIED_FOR_USER_ACCOUNT_LOCKED
      OR err_code == ER_ABORTING_USER_CONNECTION THEN drop.
    IF err_code == ER_PASSWORD_ANONYMOUS_USER THEN drop.

符号名称可以作为带引号的字符串指定,用于与字符串字段进行比较,但在这种情况下,名称是没有任何特殊意义的字符串,log_filter_dragnet 不会将它们解析为相应的数值。此外,拼写错误可能无法被检测到,而当尝试使用服务器不认识的未加引号的符号进行 SET 时,会立即发生错误。

log_filter_dragnet 规则的操作

log_filter_dragnet 在过滤规则中支持以下操作

  • drop:丢弃当前日志事件(不进行记录)。

  • throttle:应用速率限制,以降低与特定条件匹配的事件的日志冗余。参数表示速率,形式为 countcount/window_sizecount 值表示每个时间窗口允许记录的事件发生次数。 window_size 值是时间窗口(以秒为单位);如果省略,则默认窗口为 60 秒。两个值都必须是整数文字。

    此规则将插件关闭消息的节流限制为每 60 秒 5 次发生

    IF err_code == ER_PLUGIN_SHUTTING_DOWN_PLUGIN THEN throttle 5.

    此规则将错误和警告的节流限制为每小时 1000 次发生,将信息消息的节流限制为每小时 100 次发生

    IF prio <= INFORMATION THEN throttle 1000/3600 ELSE throttle 100/3600.
  • set:将值分配给字段(如果字段不存在,则创建该字段)。在后续规则中,针对字段名称的 EXISTS 测试结果为真,并且可以通过比较条件测试新值。

  • unset:丢弃字段。在后续规则中,针对字段名称的 EXISTS 测试结果为假,并且将字段与任何值进行比较的结果都为假。

    在条件只引用一个字段名称的特殊情况下,unset 后面的字段名称是可选的,unset 会丢弃命名字段。以下规则是等效的

    IF myfield == 2 THEN unset myfield.
    IF myfield == 2 THEN unset.
log_filter_dragnet 规则中的字段引用

log_filter_dragnet 规则支持引用错误事件中的核心、可选和用户定义字段。

核心字段引用

log_filter_dragnet 规则语言语法 中的语法命名了过滤规则识别的核心字段。有关这些字段的常规描述,请参阅 第 7.4.2.3 节,“错误事件字段”,假设您已经熟悉这些字段。以下说明仅提供了与 log_filter_dragnet 规则中使用的核心字段引用相关的其他信息。

  • prio

    事件优先级,表示错误、警告或提示/信息事件。在比较中,每个优先级都可以指定为符号优先级名称或整数文字。优先级符号仅在与 prio 字段进行比较时才被识别。以下比较是等效的

    IF prio == INFORMATION THEN ...
    IF prio == 3 THEN ...

    下表显示了允许的优先级级别。

    事件类型 优先级符号 数字优先级
    错误事件 ERROR 1
    警告事件 WARNING 2
    提示/信息事件 INFORMATION 3

    还存在一个 SYSTEM 消息优先级,但系统消息无法过滤,始终写入错误日志。

    优先级值遵循以下原则:优先级越高,值越低,反之亦然。优先级值从最严重事件(错误)的 1 开始,随着事件优先级的降低而增加。例如,要丢弃优先级低于警告的事件,请测试优先级值是否高于 WARNING

    IF prio > WARNING THEN drop.

    以下示例显示了用于实现与 log_error_verbosity 值类似效果的 log_filter_dragnet 规则,该值由 log_filter_internal 过滤器允许。

    • 仅错误 (log_error_verbosity=1)

      IF prio > ERROR THEN drop.
    • 错误和警告 (log_error_verbosity=2)

      IF prio > WARNING THEN drop.
    • 错误、警告和提示 (log_error_verbosity=3)

      IF prio > INFORMATION THEN drop.

      此规则实际上可以省略,因为没有大于 INFORMATIONprio 值,因此它实际上不会丢弃任何内容。

  • err_code

    数字事件错误代码。在比较中,要测试的值可以指定为符号错误名称或整数文字。错误符号仅在与 err_code 字段和用户定义字段进行比较时才被识别。以下比较是等效的

    IF err_code == ER_ACCESS_DENIED_ERROR THEN ...
    IF err_code == 1045 THEN ...
  • err_symbol

    事件错误符号,以字符串形式表示(例如,'ER_DUP_KEY')。 err_symbol 值旨在更多地用于识别日志输出中的特定行,而不是用于过滤规则比较,因为 log_filter_dragnet 不会将作为字符串指定的比较值解析为等效的数字错误代码。(要实现这一点,必须使用其未加引号的符号指定错误。)

可选字段引用

log_filter_dragnet 规则语言语法 中的语法命名了过滤规则识别的可选字段。有关这些字段的常规描述,请参阅 第 7.4.2.3 节,“错误事件字段”,假设您已经熟悉这些字段。以下说明仅提供了与 log_filter_dragnet 规则中使用的可选字段引用相关的其他信息。

  • label

    prio 值相对应的标签,以字符串形式表示。过滤规则可以更改支持自定义标签的日志接收器的标签。 label 值旨在更多地用于识别日志输出中的特定行,而不是用于过滤规则比较,因为 log_filter_dragnet 不会将作为字符串指定的比较值解析为等效的数字优先级。

  • source_file

    发生事件的源文件,不包含任何前导路径。例如,要测试 sql/gis/distance.cc 文件,请按如下方式编写比较

    IF source_file == "distance.cc" THEN ...
用户定义字段引用

log_filter_dragnet 过滤规则中,任何不被识别为核心或可选字段名称的字段名称都被视为引用用户定义字段。