Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Rule-Based Error Log Filtering (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。这条规则集将信息事件drop,其他事件中删除 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.';

一旦你设置了过滤配置为你所需,考虑使用dragnet.log_error_filter_rules通过SET PERSIST而不是SET GLOBAL使设置持久化到服务器重启。或者将设置添加到服务器选项文件中。

使用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过滤器规则语言的语法如下。每个规则都是一个以点符号.结尾的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 不会将其解析为对应的数字值。同时,拼写错误也可能被忽略,而使用未知服务器的符号时立即出现错误。

log_filter_dragnet 在过滤规则中支持这些操作:

  • drop: 删除当前日志事件(不记录它)。

  • throttle: 对于满足特定条件的事件应用速率限制以减少日志 verbosity。参数表示速率,形式为 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 规则支持错误事件中的核心、可选和自定义字段引用。

Core Field References

log_filter_dragnet 语法在log_filter_dragnet 规则语言语法中命名核心字段,filter规则识别的字段。关于这些字段的总体描述,请参阅第7.4.2.3节,“错误事件字段”,假设您已经熟悉该部分。以下注释仅提供关于核心字段引用在 log_filter_dragnet 规则中的特定信息。

  • prio

    表示错误、警告或注意/信息事件的事件优先级。在比较中,每个优先级可以指定为符号优先级名称或整数字面量。优先级符号仅在与prio字段进行比较时被识别。这些比较是等价的:

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

    以下表格显示了允许的优先级水平。

    Event Type Priority Symbol Numeric Priority
    Error event ERROR 1
    Warning event WARNING 2
    Note/information event INFORMATION 3

    还有一种消息优先级为SYSTEM,但系统消息不能被过滤总是写入错误日志。

    优先级值遵循更高的优先级具有较低的值,反之亦然。优先级值从最严重的事件(错误)开始,按优先级递减增加。例如,要丢弃优先级低于警告的事件,可以测试优先级值高于WARNING

    IF prio > WARNING THEN drop.

    以下示例显示了log_error_verbosity值允许的log_filter_internal过滤器来实现每个log_error_verbosity值的效果:

    • 只显示错误(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.

      这个规则实际上可以被省略,因为没有优先级值高于INFORMATION,因此实际上什么都丢弃不了。

  • 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不解析指定为字符串的比较值到等效的数字错误代码中(要发生该情况,必须使用未引号符号指定错误)。

Optional Field References

log_filter_dragnet语法在Grammar for log_filter_dragnet Rule Language命名可选字段,filter规则识别的。关于这些字段的总体描述,请参阅第7.4.2.3节,“Error Event Fields”,假设您已经熟悉。以下注释仅提供关于可选字段引用在log_filter_dragnet规则中的额外信息。

  • label

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

  • source_file

    事件发生的源文件,去除任何前缀路径。例如,要测试sql/gis/distance.cc文件,可以写成这样:

    IF source_file == "distance.cc" THEN ...
User-Defined Field References

log_filter_dragnet过滤规则中未识别的任何字段名将被视为用户定义的字段名。