过滤器定义是 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 |
无符号整数 | 表名长度 |
以下列表显示了哪些语句会产生哪些表访问事件
读取事件SELECTINSERT ... SELECT(对于SELECT子句中引用的表)REPLACE ... SELECT(对于SELECT子句中引用的表)UPDATE ... WHERE(对于WHERE子句中引用的表)HANDLER ... READ
删除事件DELETETRUNCATE TABLE
插入事件INSERTINSERT ... SELECT(对于INSERT子句中引用的表)REPLACEREPLACE ... SELECT(对于REPLACE子句中引用的表LOAD DATALOAD XML
更新事件UPDATEUPDATE ... 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"NONE1或"::errors"ERRORS2或"::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"NONE1或"::logins"LOGINS2或"::all"ALL3或"::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"NONE1或"::errors"ERRORS2或"::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": falsereplace:当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或deletetable_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 系统变量的值无关。