过滤器定义是 JSON
值。有关在 MySQL 中使用 JSON
数据的信息,请参阅 第 13.5 节,“JSON 数据类型”。
过滤器定义采用以下形式,其中 actions
指示如何进行过滤
{ "filter": actions }
以下讨论描述了过滤器定义中允许的结构。
要显式启用或禁用所有事件的日志记录,请在过滤器中使用 log
项
{
"filter": { "log": true }
}
log
值可以是 true
或 false
。
前面的过滤器启用所有事件的日志记录。它等效于
{
"filter": { }
}
日志记录行为取决于 log
值以及是否指定了 class
或 event
项
如果指定了
log
,则使用其给定值。如果没有指定
log
,则如果未指定class
或event
项,则日志记录为true
,否则为false
(在这种情况下,class
或event
可以包含自己的log
项)。
要记录特定类的事件,请在过滤器中使用 class
项,其 name
字段表示要记录的类的名称
{
"filter": {
"class": { "name": "connection" }
}
}
name
值可以是 connection
、general
或 table_access
,分别用于记录连接、常规或表访问事件。
前面的过滤器启用 connection
类中事件的日志记录。它等效于以下过滤器,其中 log
项是显式指定的
{
"filter": {
"log": false,
"class": { "log": true,
"name": "connection" }
}
}
要启用多个类的日志记录,请将 class
值定义为命名类的 JSON
数组元素
{
"filter": {
"class": [
{ "name": "connection" },
{ "name": "general" },
{ "name": "table_access" }
]
}
}
当给定项的多个实例出现在过滤器定义中的同一级别时,可以将这些项值组合到数组值中的该项的单个实例中。前面的定义可以这样写
{
"filter": {
"class": [
{ "name": [ "connection", "general", "table_access" ] }
]
}
}
要选择特定的事件子类,请使用包含 name
项的 event
项,该项命名子类。由 event
项选择的事件的默认操作是记录它们。例如,此过滤器为命名的事件子类启用日志记录
{
"filter": {
"class": [
{
"name": "connection",
"event": [
{ "name": "connect" },
{ "name": "disconnect" }
]
},
{ "name": "general" },
{
"name": "table_access",
"event": [
{ "name": "insert" },
{ "name": "delete" },
{ "name": "update" }
]
}
]
}
}
event
项还可以包含显式的 log
项,以指示是否记录符合条件的事件。此 event
项选择多个事件并显式指示它们的日志记录行为
"event": [
{ "name": "read", "log": false },
{ "name": "insert", "log": true },
{ "name": "delete", "log": true },
{ "name": "update", "log": true }
]
如果 event
项包含 abort
项,则它还可以指示是否阻止符合条件的事件。有关详细信息,请参阅 阻止执行特定事件。
表 8.35,“事件类和子类组合”描述了每个事件类允许的子类值。
表 8.35 事件类和子类组合
事件类 | 事件子类 | 描述 |
---|---|---|
连接 |
连接 |
连接初始化(成功或不成功) |
连接 |
更改用户 |
会话期间使用不同的用户/密码重新进行用户身份验证 |
连接 |
断开连接 |
连接终止 |
常规 |
状态 |
常规操作信息 |
消息 |
内部 |
内部生成的消息 |
消息 |
用户 |
由 audit_api_message_emit_udf() 生成的消息 |
表访问 |
读取 |
表读取语句,例如 SELECT 或 INSERT INTO ... SELECT |
表访问 |
删除 |
表删除语句,例如 DELETE 或 TRUNCATE TABLE |
表访问 |
插入 |
表插入语句,例如 INSERT 或 REPLACE |
表访问 |
更新 |
表更新语句,例如 UPDATE |
表 8.36,“每个事件类和子类组合的日志和中止特性”描述了每个事件子类是否可以记录或中止。
表 8.36 每个事件类和子类组合的日志和中止特性
事件类 | 事件子类 | 可以记录 | 可以中止 |
---|---|---|---|
连接 |
连接 |
是 | 否 |
连接 |
更改用户 |
是 | 否 |
连接 |
断开连接 |
是 | 否 |
常规 |
状态 |
是 | 否 |
消息 |
内部 |
是 | 是 |
消息 |
用户 |
是 | 是 |
表访问 |
读取 |
是 | 是 |
表访问 |
删除 |
是 | 是 |
表访问 |
插入 |
是 | 是 |
表访问 |
更新 |
是 | 是 |
可以在包含式或排除式模式下定义过滤器
包含式模式仅记录明确指定的项目。
排除式模式记录除明确指定的项目之外的所有内容。
要执行包含式日志记录,请全局禁用日志记录并为特定类启用日志记录。此过滤器记录 连接
类中的 连接
和 断开连接
事件,以及 常规
类中的事件
{
"filter": {
"log": false,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": true },
{ "name": "disconnect", "log": true }
]
},
{ "name": "general", "log": true }
]
}
}
要执行排除式日志记录,请全局启用日志记录并为特定类禁用日志记录。此过滤器记录除 常规
类中的事件之外的所有内容
{
"filter": {
"log": true,
"class":
{ "name": "general", "log": false }
}
}
此过滤器记录 连接
类中的 更改用户
事件、消息
事件和 表访问
事件,这是因为它不 记录其他所有内容
{
"filter": {
"log": true,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": false },
{ "name": "disconnect", "log": false }
]
},
{ "name": "general", "log": false }
]
}
}
要根据特定事件字段值启用日志记录,请在 日志
项目中指定一个 字段
项目,该项目指示字段名称及其预期值
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"field": { "name": "general_command.str", "value": "Query" }
}
}
}
}
}
每个事件都包含特定于事件类的字段,可以从过滤器内部访问这些字段以执行自定义过滤。
连接
类中的事件指示会话期间何时发生与连接相关的活动,例如用户连接到服务器或与服务器断开连接。表 8.37,“连接事件字段” 指示 连接
事件的允许字段。
表 8.37 连接事件字段
字段名称 | 字段类型 | 描述 |
---|---|---|
状态 |
整数 | 事件状态 0:正常 其他:失败 |
连接 ID |
无符号整数 | 连接 ID |
user.str |
字符串 | 身份验证期间指定的用户名 |
user.length |
无符号整数 | 用户名长度 |
priv_user.str |
字符串 | 已验证的用户名(帐户用户名) |
priv_user.length |
无符号整数 | 已验证的用户名长度 |
external_user.str |
字符串 | 外部用户名(由第三方身份验证插件提供) |
external_user.length |
无符号整数 | 外部用户名长度 |
proxy_user.str |
字符串 | 代理用户名 |
proxy_user.length |
无符号整数 | 代理用户名长度 |
host.str |
字符串 | 连接的用户主机 |
host.length |
无符号整数 | 连接的用户主机长度 |
ip.str |
字符串 | 连接的用户 IP 地址 |
ip.length |
无符号整数 | 连接的用户 IP 地址长度 |
database.str |
字符串 | 在连接时指定的数据库名称 |
database.length |
无符号整数 | 数据库名称长度 |
连接类型 |
整数 | 连接类型 0 或 1 或 2 或 3 或 4 或 5 或 |
"::
值是符号伪常量,可以代替文字数值给出。它们必须用引号括起来,并且区分大小写。xxx
"
常规
类中的事件指示操作的状态代码及其详细信息。表 8.38,“常规事件字段” 指示 常规
事件的允许字段。
表 8.38 常规事件字段
字段名称 | 字段类型 | 描述 |
---|---|---|
general_error_code |
整数 | 事件状态 0:正常 其他:失败 |
general_thread_id |
无符号整数 | 连接/线程 ID |
general_user.str |
字符串 | 身份验证期间指定的用户名 |
general_user.length |
无符号整数 | 用户名长度 |
general_command.str |
字符串 | 命令名称 |
general_command.length |
无符号整数 | 命令名称长度 |
general_query.str |
字符串 | SQL 语句文本 |
general_query.length |
无符号整数 | SQL 语句文本长度 |
general_host.str |
字符串 | 主机名 |
general_host.length |
无符号整数 | 主机名长度 |
general_sql_command.str |
字符串 | SQL 命令类型名称 |
general_sql_command.length |
无符号整数 | SQL 命令类型名称长度 |
general_external_user.str |
字符串 | 外部用户名(由第三方身份验证插件提供) |
general_external_user.length |
无符号整数 | 外部用户名长度 |
general_ip.str |
字符串 | 连接的用户 IP 地址 |
general_ip.length |
无符号整数 | 连接用户 IP 地址长度 |
general_command.str
指示命令名称:查询
、执行
、退出
或 更改用户
。
general_command.str
字段设置为 查询
或 执行
的 常规
事件包含设置为指定 SQL 命令类型的值的 general_sql_command.str
:alter_db
、alter_db_upgrade
、admin_commands
等。可用的 general_sql_command.str
值可以看作此语句显示的 Performance Schema 工具的最后一部分
mysql> SELECT NAME FROM performance_schema.setup_instruments
WHERE NAME LIKE 'statement/sql/%' ORDER BY NAME;
+---------------------------------------+
| NAME |
+---------------------------------------+
| statement/sql/alter_db |
| statement/sql/alter_db_upgrade |
| statement/sql/alter_event |
| statement/sql/alter_function |
| statement/sql/alter_instance |
| statement/sql/alter_procedure |
| statement/sql/alter_server |
...
表访问
类中的事件提供有关对表的特定访问类型的信息。表 8.39,“表访问事件字段” 指示 表访问
事件的允许字段。
表 8.39 表访问事件字段
字段名称 | 字段类型 | 描述 |
---|---|---|
连接 ID |
无符号整数 | 事件连接 ID |
sql_command_id |
整数 | SQL 命令 ID |
query.str |
字符串 | SQL 语句文本 |
query.length |
无符号整数 | SQL 语句文本长度 |
table_database.str |
字符串 | 与事件关联的数据库名称 |
table_database.length |
无符号整数 | 数据库名称长度 |
table_name.str |
字符串 | 与事件关联的表名 |
table_name.length |
无符号整数 | 表名长度 |
以下列表显示了哪些语句会产生哪些表访问事件
读取
事件SELECT
INSERT ... SELECT
(对于SELECT
子句中引用的表)REPLACE ... SELECT
(对于SELECT
子句中引用的表)UPDATE ... WHERE
(对于WHERE
子句中引用的表)HANDLER ... READ
删除
事件DELETE
TRUNCATE TABLE
插入
事件INSERT
INSERT ... SELECT
(对于INSERT
子句中引用的表)REPLACE
REPLACE ... SELECT
(对于REPLACE
子句中引用的表LOAD DATA
LOAD XML
更新
事件UPDATE
UPDATE ... WHERE
(对于UPDATE
子句中引用的表)
事件
项目可以包含一个 中止
项目,该项目指示是否阻止符合条件的事件执行。中止
允许编写阻止特定 SQL 语句执行的规则。
从理论上讲,具有足够权限的用户可能会错误地在审计日志过滤器中创建一个 中止
项目,从而阻止自己和其他管理员访问系统。提供 AUDIT_ABORT_EXEMPT
权限是为了允许用户帐户的查询始终得到执行,即使 中止
项目会阻止它们也是如此。因此,如果审计配置错误,则可以使用具有此权限的帐户重新获得对系统的访问权限。查询仍记录在审计日志中,但由于拥有权限,因此不会被拒绝,而是被允许。
使用 SYSTEM_USER
权限创建的帐户在创建时会自动分配 AUDIT_ABORT_EXEMPT
权限。如果您执行升级过程,并且没有现有帐户分配了 AUDIT_ABORT_EXEMPT
权限,则也会将 AUDIT_ABORT_EXEMPT
权限分配给具有 SYSTEM_USER
权限的现有帐户。
中止
项目必须出现在 事件
项目中。例如
"event": {
"name": qualifying event subclass names
"abort": condition
}
对于 名称
项目选择的事件子类,中止
操作为 true 或 false,具体取决于 条件
求值。如果条件的计算结果为 true,则该事件将被阻止。否则,该事件将继续执行。
条件
规范可以像 true
或 false
一样简单,也可以更复杂,以便求值取决于事件特征。
此过滤器阻止 INSERT
、UPDATE
和 DELETE
语句
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [ "insert", "update", "delete" ],
"abort": true
}
}
}
}
这个更复杂的过滤器会阻止相同的语句,但仅针对特定表(finances.bank_account
)
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [ "insert", "update", "delete" ],
"abort": {
"and": [
{ "field": { "name": "table_database.str", "value": "finances" } },
{ "field": { "name": "table_name.str", "value": "bank_account" } }
]
}
}
}
}
}
由过滤器匹配和阻止的语句会向客户端返回错误
ERROR 1045 (28000): Statement was aborted by an audit log filter
并非所有事件都可以被阻止(请参阅 表 8.36,“每个事件类和子类组合的日志和中止特性”)。对于无法阻止的事件,审计日志会向错误日志写入警告,而不是阻止它。
对于尝试定义 中止
项目出现在 事件
项目之外的过滤器,会发生错误。
逻辑运算符(和
、或
、非
)允许构造复杂的条件,从而能够编写更高级的过滤配置。以下 日志
项目仅记录 general_command
字段具有特定值和长度的 常规
事件
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"or": [
{
"and": [
{ "field": { "name": "general_command.str", "value": "Query" } },
{ "field": { "name": "general_command.length", "value": 5 } }
]
},
{
"and": [
{ "field": { "name": "general_command.str", "value": "Execute" } },
{ "field": { "name": "general_command.length", "value": 7 } }
]
}
]
}
}
}
}
}
要引用 日志
条件中的预定义变量,请使用 变量
项目,该项目采用 名称
和 值
项目,并测试命名变量与给定值是否相等
"variable": {
"name": "variable_name",
"value": comparison_value
}
如果 variable_name
的值为 comparison_value
,则为 true,否则为 false。
示例
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"variable": {
"name": "audit_log_connection_policy_value",
"value": "::none"
}
}
}
}
}
}
每个预定义变量都对应一个系统变量。通过编写测试预定义变量的过滤器,您可以通过设置相应的系统变量来修改过滤器操作,而无需重新定义过滤器。例如,通过编写一个测试 audit_log_connection_policy_value
预定义变量值的过滤器,您可以通过更改 audit_log_connection_policy
系统变量的值来修改过滤器操作。
audit_log_
系统变量用于已弃用的旧模式审计日志(请参阅第 8.4.5.10 节 “旧模式审计日志过滤”)。使用基于规则的审计日志过滤时,这些变量仍然可见(例如,使用 xxx
_policySHOW VARIABLES
),但除非您编写包含引用它们的构造的过滤器,否则对它们的更改不会生效。
以下列表描述了 variable
项目允许的预定义变量
audit_log_connection_policy_value
此变量对应于
audit_log_connection_policy
系统变量的值。该值是一个无符号整数。表 8.40 “audit_log_connection_policy_value 值” 显示了允许的值和相应的audit_log_connection_policy
值。表 8.40 audit_log_connection_policy_value 值
值 对应的 audit_log_connection_policy 值 0
或"::none"
NONE
1
或"::errors"
ERRORS
2
或"::all"
ALL
"::
值是符号伪常量,可以代替文字数值给出。它们必须用引号括起来,并且区分大小写。xxx
"audit_log_policy_value
此变量对应于
audit_log_policy
系统变量的值。该值是一个无符号整数。表 8.41 “audit_log_policy_value 值” 显示了允许的值和相应的audit_log_policy
值。表 8.41 audit_log_policy_value 值
值 对应的 audit_log_policy 值 0
或"::none"
NONE
1
或"::logins"
LOGINS
2
或"::all"
ALL
3
或"::queries"
QUERIES
"::
值是符号伪常量,可以代替文字数值给出。它们必须用引号括起来,并且区分大小写。xxx
"audit_log_statement_policy_value
此变量对应于
audit_log_statement_policy
系统变量的值。该值是一个无符号整数。表 8.42 “audit_log_statement_policy_value 值” 显示了允许的值和相应的audit_log_statement_policy
值。表 8.42 audit_log_statement_policy_value 值
值 对应的 audit_log_statement_policy 值 0
或"::none"
NONE
1
或"::errors"
ERRORS
2
或"::all"
ALL
"::
值是符号伪常量,可以代替文字数值给出。它们必须用引号括起来,并且区分大小写。xxx
"
要在 log
条件中引用预定义函数,请使用 function
项目,该项目分别使用 name
和 args
项目来指定函数名称及其参数
"function": {
"name": "function_name",
"args": arguments
}
name
项目应仅指定函数名称,不带括号或参数列表。
args
项目必须满足以下条件
如果函数不带参数,则不应提供
args
项目。如果函数确实需要参数,则需要一个
args
项目,并且必须按照函数说明中列出的顺序提供参数。参数可以引用预定义变量、事件字段或字符串或数值常量。
如果参数数量不正确或参数不是函数所需的正确数据类型,则会发生错误。
示例
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"function": {
"name": "find_in_include_list",
"args": [ { "string": [ { "field": "user.str" },
{ "string": "@"},
{ "field": "host.str" } ] } ]
}
}
}
}
}
}
前面的过滤器根据当前用户是否在 audit_log_include_accounts
系统变量中找到来确定是否记录 general
类 status
事件。该用户是使用事件中的字段构造的。
以下列表描述了 function
项目允许的预定义函数
audit_log_exclude_accounts_is_null()
检查
audit_log_exclude_accounts
系统变量是否为NULL
。此函数在定义与旧审计日志实现相对应的过滤器时非常有用。参数
无。
audit_log_include_accounts_is_null()
检查
audit_log_include_accounts
系统变量是否为NULL
。此函数在定义与旧审计日志实现相对应的过滤器时非常有用。参数
无。
debug_sleep(毫秒)
休眠指定的毫秒数。此函数在性能测量期间使用。
debug_sleep()
仅适用于调试版本。参数
毫秒
:一个无符号整数,指定要休眠的毫秒数。
find_in_exclude_list(帐户)
检查审计日志排除列表(
audit_log_exclude_accounts
系统变量的值)中是否存在帐户字符串。参数
帐户
:指定用户帐户名称的字符串。
find_in_include_list(帐户)
检查审计日志包含列表(
audit_log_include_accounts
系统变量的值)中是否存在帐户字符串。参数
帐户
:指定用户帐户名称的字符串。
query_digest([字符串])
此函数的行为因是否提供参数而异
如果没有参数,
query_digest
将返回与当前事件中的语句文本相对应的语句摘要值。如果提供参数,
query_digest
将返回一个布尔值,指示该参数是否等于当前语句摘要。
参数
字符串
:此参数是可选的。如果提供,它指定要与当前事件中语句的摘要进行比较的语句摘要。
示例
此
function
项目不包含参数,因此query_digest
返回当前语句摘要作为字符串"function": { "name": "query_digest" }
此
function
项目包含一个参数,因此query_digest
返回一个布尔值,指示该参数是否等于当前语句摘要"function": { "name": "query_digest", "args": "SELECT ?" }
string_find(文本, 子字符串)
检查
子字符串
值是否包含在文本
值中。此搜索区分大小写。参数
文本
:要搜索的文本字符串。子字符串
:要在文本
中搜索的子字符串。
审计过滤器定义支持替换某些审计事件字段,以便记录的事件包含替换值而不是原始值。此功能使记录的审计记录能够包含语句摘要而不是文本语句,这对于语句可能暴露敏感值的 MySQL 部署非常有用。
审计事件中的字段替换的工作原理如下
字段替换在审计过滤器定义中指定,因此必须按照 第 8.4.5.7 节 “审计日志过滤” 中的说明启用审计日志过滤。
并非所有字段都可以替换。表 8.43 “可替换的事件字段” 显示了哪些字段在哪些事件类中是可替换的。
替换是有条件的。过滤器定义中的每个替换规范都包含一个条件,可以根据条件结果更改或保留可替换字段。
如果发生替换,替换规范将使用为此目的允许的函数指示替换值。
如 表 8.43 “可替换的事件字段” 所示,当前唯一可替换的字段是包含语句文本的字段(出现在 general
和 table_access
类的事件中)。此外,唯一允许用于指定替换值的函数是 query_digest
。这意味着唯一允许的替换操作是用其对应的摘要替换语句文本。
由于字段替换发生在早期审计阶段(在过滤期间),因此无论以后写入的日志格式如何(即,审计日志插件是生成 XML 还是 JSON 输出),选择写入语句文本还是摘要值都适用。
字段替换可以在不同的事件粒度级别进行
要对类中的所有事件执行字段替换,请在类级别过滤事件。
要在更细粒度的基础上执行替换,请包含其他事件选择项目。例如,您可以仅对给定事件类的特定子类执行字段替换,或者仅对字段具有某些特征的事件执行字段替换。
在过滤器定义中,通过包含 print
项目来指定字段替换,该项目具有以下语法
"print": {
"field": {
"name": "field_name",
"print": condition,
"replace": replacement_value
}
}
在 print
项目中,其 field
项目采用以下三个项目来指示是否以及如何进行替换
name
:要替换的字段(可能)。field_name
必须是 表 8.43 “可替换的事件字段” 中显示的字段之一。print
:确定是保留原始字段值还是替换它的条件如果
condition
的计算结果为true
,则该字段保持不变。如果
condition
的计算结果为false
,则使用replace
项目的值进行替换。
要无条件地替换字段,请像这样指定条件
"print": false
replace
:当print
条件的计算结果为false
时要使用的替换值。使用function
项目指定replacement_value
。
例如,此过滤器定义适用于 general
类中的所有事件,用其摘要替换语句文本
{
"filter": {
"class": {
"name": "general",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
前面的过滤器使用此 print
项目无条件地将 general_query.str
中包含的语句文本替换为其摘要值
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
print
项目可以用不同的方式编写,以实现不同的替换策略。刚刚显示的 replace
项目使用此 function
构造指定替换文本,以返回表示当前语句摘要的字符串
"function": {
"name": "query_digest"
}
query_digest
函数也可以用另一种方式使用,作为返回布尔值的比较器,这使得它可以在 print
条件中使用。为此,请提供一个指定比较语句摘要的参数
"function": {
"name": "query_digest",
"args": "digest"
}
在这种情况下,query_digest
根据当前语句摘要是否与比较摘要相同返回 true
或 false
。以这种方式使用 query_digest
使过滤器定义能够检测与特定摘要匹配的语句。以下构造中的条件仅对摘要等于 SELECT ?
的语句为 true,因此仅对与摘要不匹配的语句执行替换
"print": {
"field": {
"name": "general_query.str",
"print": {
"function": {
"name": "query_digest",
"args": "SELECT ?"
}
},
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
要仅对与摘要匹配的语句执行替换,请使用 not
来反转条件。
"print": {
"field": {
"name": "general_query.str",
"print": {
"not": {
"function": {
"name": "query_digest",
"args": "SELECT ?"
}
}
},
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
假设您希望审核日志只包含语句摘要,而不包含字面语句。为此,您必须对包含语句文本的所有事件执行替换,即 general
和 table_access
类中的事件。前面的过滤器定义展示了如何无条件地替换 general
事件中的语句文本。要对 table_access
事件执行相同的操作,请使用类似的过滤器,但将类从 general
更改为 table_access
,并将字段名从 general_query.str
更改为 query.str
。
{
"filter": {
"class": {
"name": "table_access",
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
组合 general
和 table_access
过滤器会生成一个过滤器,该过滤器对所有包含语句文本的事件执行替换。
{
"filter": {
"class": [
{
"name": "general",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
},
{
"name": "table_access",
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
]
}
}
要仅对类中的一些事件执行替换,请向过滤器添加项目,以更具体地指示何时进行替换。以下过滤器应用于 table_access
类中的事件,但仅对 insert
和 update
事件执行替换(保持 read
和 delete
事件不变)。
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [
"insert",
"update"
],
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
}
此过滤器对与列出的帐户管理语句相对应的 general
类事件执行替换(其效果是在语句中隐藏凭据和数据值)。
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
},
"log": {
"or": [
{
"field": {
"name": "general_sql_command.str",
"value": "alter_user"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "alter_user_default_role"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "create_role"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "create_user"
}
}
]
}
}
}
}
}
有关可能的 general_sql_command.str
值的信息,请参阅 测试事件字段值。
在某些情况下,可以动态更改过滤器定义。为此,请在现有的 filter
中定义 filter
配置。例如:
{
"filter": {
"id": "main",
"class": {
"name": "table_access",
"event": {
"name": [ "update", "delete" ],
"log": false,
"filter": {
"class": {
"name": "general",
"event" : { "name": "status",
"filter": { "ref": "main" } }
},
"activate": {
"or": [
{ "field": { "name": "table_name.str", "value": "temp_1" } },
{ "field": { "name": "table_name.str", "value": "temp_2" } }
]
}
}
}
}
}
}
当子过滤器中的 activate
项的值为 true
时,将激活新的过滤器。不允许在顶级 filter
中使用 activate
。
可以使用子过滤器中的 ref
项来引用原始过滤器 id
,从而将新过滤器替换为原始过滤器。
所示过滤器的运作方式如下:
main
过滤器等待table_access
事件,可以是update
或delete
。如果
update
或delete
table_access
事件发生在temp_1
或temp_2
表上,则过滤器将替换为内部过滤器(没有id
,因为不需要显式引用它)。如果发出命令结束信号(
general
/status
事件),则会向审核日志文件写入一个条目,并将过滤器替换为main
过滤器。
该过滤器可用于记录从 temp_1
或 temp_2
表更新或删除任何内容的语句,例如:
UPDATE temp_1, temp_3 SET temp_1.a=21, temp_3.a=23;
该语句会生成多个 table_access
事件,但审核日志文件仅包含 general
/ status
条目。
定义中使用的任何 id
值都仅在该定义范围内进行评估。它们与 audit_log_filter_id
系统变量的值无关。