文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  编写审计日志过滤器定义

8.4.5.8 编写审计日志过滤器定义

过滤器定义是 JSON 值。有关在 MySQL 中使用 JSON 数据的信息,请参阅 第 13.5 节,“JSON 数据类型”

过滤器定义采用以下形式,其中 actions 指示如何进行过滤

{ "filter": actions }

以下讨论描述了过滤器定义中允许的结构。

记录所有事件

要显式启用或禁用所有事件的日志记录,请在过滤器中使用 log

{
  "filter": { "log": true }
}

log 值可以是 truefalse

前面的过滤器启用所有事件的日志记录。它等效于

{
  "filter": { }
}

日志记录行为取决于 log 值以及是否指定了 classevent

  • 如果指定了 log,则使用其给定值。

  • 如果没有指定 log,则如果未指定 classevent 项,则日志记录为 true,否则为 false(在这种情况下,classevent 可以包含自己的 log 项)。

记录特定事件类

要记录特定类的事件,请在过滤器中使用 class 项,其 name 字段表示要记录的类的名称

{
  "filter": {
    "class": { "name": "connection" }
  }
}

name 值可以是 connectiongeneraltable_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() 生成的消息
表访问 读取 表读取语句,例如 SELECTINSERT INTO ... SELECT
表访问 删除 表删除语句,例如 DELETETRUNCATE TABLE
表访问 插入 表插入语句,例如 INSERTREPLACE
表访问 更新 表更新语句,例如 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 或 "::undefined":未定义

1 或 "::tcp/ip":TCP/IP

2 或 "::socket":套接字

3 或 "::named_pipe":命名管道

4 或 "::ssl":带加密的 TCP/IP

5 或 "::shared_memory":共享内存


"::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.stralter_dbalter_db_upgradeadmin_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,则该事件将被阻止。否则,该事件将继续执行。

条件 规范可以像 truefalse 一样简单,也可以更复杂,以便求值取决于事件特征。

此过滤器阻止 INSERTUPDATEDELETE 语句

{
  "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_xxx_policy 系统变量用于已弃用的旧模式审计日志(请参阅第 8.4.5.10 节 “旧模式审计日志过滤”)。使用基于规则的审计日志过滤时,这些变量仍然可见(例如,使用 SHOW 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 项目,该项目分别使用 nameargs 项目来指定函数名称及其参数

"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 系统变量中找到来确定是否记录 generalstatus 事件。该用户是使用事件中的字段构造的。

以下列表描述了 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_query.str
    表访问 query.str

  • 替换是有条件的。过滤器定义中的每个替换规范都包含一个条件,可以根据条件结果更改或保留可替换字段。

  • 如果发生替换,替换规范将使用为此目的允许的函数指示替换值。

表 8.43 “可替换的事件字段” 所示,当前唯一可替换的字段是包含语句文本的字段(出现在 generaltable_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 根据当前语句摘要是否与比较摘要相同返回 truefalse。以这种方式使用 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"
      }
    }
  }
}

假设您希望审核日志只包含语句摘要,而不包含字面语句。为此,您必须对包含语句文本的所有事件执行替换,即 generaltable_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"
            }
          }
        }
      }
    }
  }
}

组合 generaltable_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 类中的事件,但仅对 insertupdate 事件执行替换(保持 readdelete 事件不变)。

{
  "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 事件,可以是 updatedelete

  • 如果 updatedelete table_access 事件发生在 temp_1temp_2 表上,则过滤器将替换为内部过滤器(没有 id,因为不需要显式引用它)。

  • 如果发出命令结束信号(general / status 事件),则会向审核日志文件写入一个条目,并将过滤器替换为 main 过滤器。

该过滤器可用于记录从 temp_1temp_2 表更新或删除任何内容的语句,例如:

UPDATE temp_1, temp_3 SET temp_1.a=21, temp_3.a=23;

该语句会生成多个 table_access 事件,但审核日志文件仅包含 general / status 条目。

注意

定义中使用的任何 id 值都仅在该定义范围内进行评估。它们与 audit_log_filter_id 系统变量的值无关。