8.4.5.8 编写审计日志过滤器定义
过滤器定义是JSON
值。关于在 MySQL 中使用JSON
数据的信息,请参见第13.5节,“JSON数据类型”。
过滤器定义有这个形式,其中actions
表示过滤操作的方式:
{ "filter": actions }
下面讨论了过滤定义中的允许构造。
要明确地启用或禁用所有事件的日志记录,使用log
项:
{
"filter": { "log": true }
}
log值可以是true
或false
前面的过滤器启用了所有事件的日志记录。它等同于:
{
"filter": { }
}
日志行为取决于log
值和是否指定了class
或event
项:
-
如果指定了
log
,则使用其给定的值。 -
如果没有指定
log
,日志记录是true
,除非指定了class
或event
项,可以包含自己的log
项。
要记录特定类别的事件,使用class
项,在其name
字段中指定要记录的类别名称:
{
"filter": {
"class": { "name": "connection" }
}
}
该name
值可以是connection
、general
或table_access
,分别记录连接、总体或表访问事件。
前面的过滤器启用了连接类别的事件日志。它等同于以下明确指定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" ] }
]
}
}
要选择特定事件子类别,使用event
项,其中包含一个name
项,名称这些子类别。默认情况下,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 }
]
事件项还可以指示是否阻止符合条件的事件,如果包含abort
项。详细信息请见阻止特定事件的执行。
表8.35,“事件类别和子类组合”描述了每个事件类别的允许子类值。
表8.35 事件类别和子类组合
Event Class | Event Subclass | Description |
---|---|---|
connection |
connect |
连接初始化(成功或失败) |
connection |
change_user |
会话中用户重新身份验证 |
connection |
disconnect |
连接终止 |
general |
status |
通用操作信息 |
message |
internal |
内部生成的消息 |
message |
user |
由audit_api_message_emit_udf() 生成的消息 |
table_access |
read |
表读语句,例如SELECT 或INSERT INTO ... SELECT |
table_access |
delete |
表删除语句,例如DELETE 或TRUNCATE TABLE |
table_access |
insert |
表插入语句,例如INSERT 或REPLACE |
table_access |
update |
表更新语句,例如UPDATE |
表8.36,“事件类别和子类组合的日志和中止特征”对每个事件子类描述是否可以被记录或中止。
表8.36 事件类别和子类组合的日志和中止特征
Event Class | Event Subclass | Can be Logged | Can be Aborted |
---|---|---|---|
connection |
connect |
是 | 否 |
connection |
change_user |
是 | 否 |
connection |
disconnect |
是 | 否 |
general |
status |
是 | 否 |
message |
internal |
是 | 是 |
message |
user |
是 | 是 |
table_access |
read |
是 | 是 |
table_access |
delete |
是 | 是 |
table_access |
insert |
是 | 是 |
table_access |
update |
是 | 是 |
过滤器可以在包容模式或排他模式下定义:
-
包容模式仅记录明确指定的项目。
-
排他模式记录除明确指定项目外的所有项目。
要执行包容式日志记录,先禁用全局日志,然后启用特定类别的日志。这款过滤器在connection
类别中记录connect
和disconnect
事件,在general
类别中记录事件:
{
"filter": {
"log": false,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": true },
{ "name": "disconnect", "log": true }
]
},
{ "name": "general", "log": true }
]
}
}
要执行排他式日志记录,先启用全局日志,然后禁用特定类别的日志。这款过滤器记录除general
类别外的所有事件:
{
"filter": {
"log": true,
"class":
{ "name": "general", "log": false }
}
}
这款过滤器在connection
类别中记录change_user
事件,在message
事件和table_access
事件中记录事件,因为它不记录其他事件:
{
"filter": {
"log": true,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": false },
{ "name": "disconnect", "log": false }
]
},
{ "name": "general", "log": false }
]
}
}
要根据特定事件字段值启用日志记录,指定field
项目,该项目指示字段名称和预期值:
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"field": { "name": "general_command.str", "value": "Query" }
}
}
}
}
}
每个事件都包含特定类别的字段,可以从过滤器中访问以执行自定义过滤。
在connection
类别的事件指示会话期间连接相关活动的发生,例如用户连接到或从服务器断开。 表8.37,“连接事件字段” 指示了connection
事件的允许字段。
表8.37 连接事件字段
Field Name | Field Type | Description |
---|---|---|
status |
事件状态: 0:OK 否则:Failed |
|
connection_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 |
无符号整数 | 数据库名称长度 |
connection_type |
整数 |
连接类型: 0 或 1 或 2 或 3 或 4 或 5 或 |
"::
值是符号伪常量,可以代替字面值。它们必须被字符串引起来,并且大小写敏感。xxx
"
一般事件在 general
类中表示操作的状态码和详细信息。表 8.38,“一般事件字段” 指示了 general
事件的允许字段。
表 8.38 一般事件字段
Field Name | Field Type | Description |
---|---|---|
general_error_code |
整数 |
事件状态: 0:OK 否则:Failed |
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 |
无符号整数 | 命令类型名称长度 |
general_external_user.str |
字符串 | 第三方身份验证插件提供的外部用户名 |
general_external_user.length |
无符号整数 | 外部用户名长度 |
general_ip.str |
字符串 | 连接用户 IP 地址 |
general_ip.length |
无符号整数 | 连接用户 IP 地址长度 |
general_command.str
表示命令名称:Query
、Execute
、Quit
或 Change user
。
一个general
事件,general_command.str
字段设置为Query
或Execute
,包含general_sql_command.str
字段,值指定SQL命令类型:alter_db
、alter_db_upgrade
、admin_commands
等。可用的general_sql_command.str
值可以在这个语句中显示的性能架构仪表盘最后一个组件中看到:
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 |
...
一个table_access
事件提供关于某个表的特定访问信息。8.39, “表访问事件字段”指示table_access
事件的允许字段。
8.39 表访问事件字段
Field Name | Field Type | Description |
---|---|---|
connection_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 |
无符号整数 | 表名称长度 |
以下列表显示哪些语句产生哪些表访问事件:
-
read
事件:-
SELECT
-
INSERT ... SELECT
(对SELECT
子句中引用的表) -
REPLACE ... SELECT
(对SELECT
子句中引用的表) -
UPDATE ... WHERE
(对WHERE
子句中引用的表) -
HANDLER ... READ
-
-
delete
事件:-
DELETE
-
TRUNCATE TABLE
-
-
insert
事件:-
INSERT
-
INSERT ... SELECT
(对INSERT
子句中引用的表) -
REPLACE
-
REPLACE ... SELECT
(对REPLACE
子句中引用的表) -
LOAD DATA
-
LOAD XML
-
-
update
事件:-
UPDATE
-
UPDATE ... WHERE
(对UPDATE
子句中引用的表)
-
event
项可以包括一个abort
项,指示是否阻止符合条件的事件执行。abort
可以编写规则来阻止特定的SQL语句执行。
理论上,拥有足够权限的用户可能会误创建一个在审核日志过滤器中阻止自己和其他管理员访问系统的abort
项。可用AUDIT_ABORT_EXEMPT
特权来允许用户账户的查询始终执行,即使abort
项会阻止它们。拥有这个特权的账户可以用来恢复在审核配置错误后访问系统。该查询仍然被记录到审核日志中,但由于特权而不是被拒绝。
使用SYSTEM_USER
特权创建的账户自动分配AUDIT_ABORT_EXEMPT
特权。同时,在升级过程中,如果没有账户拥有这个特权,系统也会将其分配给已有的账户。
"event": {
"name": qualifying event subclass names
"abort": condition
}
在event
项中必须出现abort
项。例如:
条件指定可以是简单的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,“事件类别和子类组合的日志和中断特征”)。对于不能被阻止的事件,审核日志写入错误日志,而不是阻止它。
对定义过滤器,其中abort
项出现在非event
项中,出现错误。
逻辑运算符
逻辑操作符(and
, or
, not
) 允许构建复杂的条件,实现更高级别的过滤配置。以下log
项仅记录具有特定值和长度的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 } }
]
}
]
}
}
}
}
}
要在log
条件中引用预定义变量,使用variable
项,它将name
和value
项,并测试命名变量与给定值的等价性:
"variable": {
"name": "variable_name",
"value": comparison_value
}
如果variable_name
具有值comparison_value
,则为真,否则为假。
示例:
{
"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 值
Value Corresponding audit_log_connection_policy Value 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 值
Value Corresponding audit_log_policy Value 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 值
Value Corresponding audit_log_statement_policy Value 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
。这个函数可以帮助定义与legacy审核日志实现对应的过滤器。参数:
无。
-
audit_log_include_accounts_is_null()
检查
audit_log_include_accounts
系统变量是否为NULL
。这个函数在定义与legacy audit log 实现对应的过滤器时非常有用。参数:
无。
-
debug_sleep(millisec)
睡眠给定的毫秒数。这个函数用于性能测量。
debug_sleep()
只在调试版本中可用。参数:
-
millisec
: 无符号整数,指定睡眠的毫秒数。
-
-
find_in_exclude_list(account)
检查账户字符串是否在audit log 排除列表中(
audit_log_exclude_accounts
系统变量的值)。参数:
-
account
: 指定用户账户名称的字符串。
-
-
find_in_include_list(account)
检查账户字符串是否在audit log 包含列表中(
audit_log_include_accounts
系统变量的值)。参数:
-
account
: 指定用户账户名称的字符串。
-
-
query_digest([str])
这个函数的行为取决于是否给出参数:
-
无参数时,
query_digest
返回当前事件的语句摘要值。 -
有参数时,
query_digest
返回一个布尔值,表示参数是否等于当前语句摘要。
参数:
-
str
:这个参数是可选的。如果给出,它指定要与当前事件中的语句摘要进行比较。
示例:
这个
function
项不包括参数,所以query_digest
返回当前语句摘要作为字符串:"function": { "name": "query_digest" }
这个
function
项包括参数,所以query_digest
返回一个布尔值,表示参数是否等于当前语句摘要:"function": { "name": "query_digest", "args": "SELECT ?" }
-
-
string_find(text, substr)
检查
substr
值是否包含在text
值中。这一搜索是大小写敏感的。参数:
-
text
:要搜索的文本字符串。 -
substr
:在text
中搜索的子串。
-
审核过滤器定义支持将某些审核事件字段替换为特定的值,以便logged事件包含替换后的值,而不是原始值。这一能力使得logged审核记录可以包含语句摘要,而不是literal语句,这对MySQL部署非常有用,因为语句可能会暴露敏感信息。
审核事件中的字段替换工作方式如下:
-
字段替换是在审核过滤器定义中指定的,因此,必须启用审核日志 filtering,如第8.4.5.7节,“审核日志 filtering”所述。
-
不所有字段都可以被替换。表 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
这样可以使过滤器定义检测特定的摘要语句。前面的构造中的条件只对不匹配摘要的语句为真,从而只有不匹配的语句才会被替换:
"print": {
"field": {
"name": "general_query.str",
"print": {
"function": {
"name": "query_digest",
"args": "SELECT ?"
}
},
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
要仅对匹配 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
事件 unconditional 地替换语句文本。要对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
时,新过滤器就被激活。使用activate
在顶级filter
中不允许。
可以将新的过滤器替换为原始的过滤器,通过在子过滤器中使用ref
项来引用原始过滤器id
。
这个过滤器的操作方式是:
-
主过滤器等待
table_access
事件,包括update
或delete
。 -
如果在
temp_1
或temp_2
表上发生update
或delete
table_access
事件,过滤器将被替换为内部的过滤器(因为不需要明确引用)。 -
如果命令结束(
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
系统变量的值相关。