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
}
简单条件比较字段与值或测试字段存在性。构建更复杂的条件,使用AND
和OR
操作符。两个操作符具有相同的优先级,左至右评估。
在字符串中要逃逸一个字符,前面加反斜杠\
。反斜杠用于包含反斜杠本身或字符串引号字符,其他字符可选。
log_filter_dragnet
支持某些字段的符号名称对比。为了便捷和可读性,符号值在可能的情况下优先于数字值。
-
事件优先级值1、2和3可以指定为
ERROR
、WARNING
和INFORMATION
。优先级符号只在与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。参数表示速率,形式为count
或count
/window_size
。count
值表示每个时间窗口内允许的事件出现次数。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
过滤规则中未识别的任何字段名将被视为用户定义的字段名。