暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

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

原创 由迪 2020-07-30
533

log_filter_dragnet的日志过滤器组件能够基于用户定义的规则日志过滤。要定义适用的规则,请设置 dragnet.log_error_filter_rules 系统变量。

要启用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为在服务器启动时生效,请使用 第5.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

示例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使设置在服务器重新启动后持续存在。或者,将设置添加到服务器选项文件。

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

SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal';

同样,请考虑使用using 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
  | label
  | err_code
  | err_symbol
  | SQL_state
  | subsystem
}

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

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可被指定为 ERRORWARNING,和 INFORMATION。仅在与该prio字段进行比较时才能识别优先级符号 。这些比较是等效的:

    IF prio == INFORMATION THEN ... IF prio == 3 THEN ...
  • 错误代码可以以数字形式或作为相应的错误符号指定。例如, ER_STARTUP是error的符号名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,确定错误符号:

    shell> 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_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针对字段名称的测试为true,并且可以通过比较条件来测试新值。

  • unset:丢弃字段。在后续规则中,EXISTS针对字段名称的测试为false,而针对任何值的字段比较为false。

    在特殊情况下,该条件仅指一个字段名,后面的字段名 unset是可选的,并 unset丢弃命名字段。这些规则是等效的:

    IF myfield == 2 THEN unset myfield. IF myfield == 2 THEN unset.
log_filter_dragnet规则字段

log_filter_dragnet 支持规则中的核心,可选和用户定义的字段:

  • 将为错误事件自动设置一个核心字段。但是,不能保证其在事件中的存在,因为核心字段(如任何类型的字段)可能未由过滤规则设置。如果是这样,将发现该规则集内的后续规则以及过滤器之后执行的组件(例如日志编写器)缺少该字段。
  • 通常不存在可选字段,但对于某些事件类型可能存在该字段。如果存在,则可选字段会提供适当且可用的其他事件信息。
  • 用户定义的字段是名称尚未定义为核心或可选字段的任何字段。在使用set操作创建之前,用户定义的字段不存在 。

如前面的描述所暗示,任何给定的字段都可能不存在,因为它根本就不存在,或者由于过滤规则而被丢弃。对于日志编写者,缺少字段的影响是特定于编写者的。例如,编写者可能会从日志消息中忽略该字段,指示该字段丢失,或替换为默认值。如有疑问,请使用过滤器规则取消设置该字段,然后检查日志编写器对该字段的作用。

这些字段是核心字段:

  • time

    事件时间戳记。

  • msg

    事件消息字符串。

  • prio

    事件优先级,用于指示错误,警告或注释/信息事件。此字段对应于中的严重性syslog

    在比较中,可以将每个优先级指定为符号优先级名称或整数文字。仅在与该prio字段进行比较时才能识别优先级符号 。这些比较是等效的:

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

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

    事件类型 优先符号 数值优先
    错误事件 ERROR 1个
    警告事件 WARNING 2
    笔记/信息事件 INFORMATION 3

    优先级也为SYSTEM,但是系统消息无法过滤,并且始终写入错误日志。

    通常,消息优先级的确定如下:

    情况或事件是否可行?

    • 是:情况或事件可忽略吗?
      • 是:优先级为WARNING
      • 否:优先级为ERROR
    • 否:这种情况或事件是强制性的吗?
      • 是:优先级为SYSTEM
      • 否:优先级为INFORMATION

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

    IF prio > WARNING THEN drop.

    以下示例显示了log_filter_dragnet实现类似于 过滤器log_error_verbosity允许的每个值的效果的 规则 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.

      实际上,可以忽略此规则,因为没有 prio大于的值 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不能将指定为字符串的比较值解析为等效的数字错误代码。

  • SQL_state

    事件SQLSTATE值,以字符串形式(例如 '23000')。

  • subsystem

    发生事件的子系统。可能的值为InnoDBInnoDB存储引擎), Repl(复制子系统), Server(否则)。

可选字段分为以下几类:

有关错误的其他信息,例如操作系统发出的错误或错误标签:

  • OS_errno

    操作系统错误号。

  • OS_errmsg

    操作系统错误消息。

  • label

    prio 值对应的标签,以字符串形式。筛选器规则可以为支持自定义标签的日志编写器更改标签。 label值比过滤器规则比较中更多地用于标识日志输出中的特定行,因为它们 log_filter_dragnet不能将指定为字符串的比较值解析为等效的数字优先级。

标识事件发生的客户端:

  • user

    客户端用户。

  • host

    客户端主机。

  • thread

    线程ID。

  • query_id

    查询ID。

调试信息:

  • source_file

    发生事件的源文件。文件名应省略任何前导路径。例如,要测试 sql/gis/distance.cc文件,请编写如下比较:

    IF source_file == "distance.cc" THEN ...
  • source_line

    源文件中发生事件的行。

  • function

    事件发生的功能。

  • component

    发生事件的组件或插件。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论