Skip to content

Rate this page
Thanks for your feedback
Thank you! The feedback has been submitted.

For help, click the link below to get free database assistance or contact our experts for personalized support.

Filter the Audit Log Filter logs

Rule-based filtering includes or excludes events using these attributes:

  • User account
  • Audit event class
  • Audit event subclass
  • Audit event fields (for example, COMMAND_CLASS or STATUS)

Which classes and subclasses you can target depends on audit_log_filter.event_mode. Validated names appear in Audit Log Filter definition fields.

Define multiple filters and assign any filter to multiple accounts, or register a default filter for accounts without a specific row. You define filters through SQL function calls.

After you define a filter, the server persists it in mysql system tables.

Audit Log Filter functions

Audit Log filter functions require AUDIT_ADMIN or SUPER.

These functions drive rule-based filtering:

Function Description Example
audit_log_filter_flush() Flush filter tables and reload definitions into the component SELECT audit_log_filter_flush();
audit_log_filter_set_filter() Create or replace a named filter SELECT audit_log_filter_set_filter('log_connections', '{ "filter": {} }');
audit_log_filter_remove_filter() Drop a named filter SELECT audit_log_filter_remove_filter('filter-name');
audit_log_filter_set_user() Bind a filter to a user account SELECT audit_log_filter_set_user('user-name@localhost', 'filter-name');
audit_log_filter_remove_user() Clear filter bindings for a user account SELECT audit_log_filter_remove_user('user-name@localhost');

Through SQL, you define, inspect, and change audit log filters; definitions live in the mysql system database.

audit_log_session_filter_id() returns the active audit log filter ID for the current session.

Filter definitions are JSON values.

Reloading rules from tables, persistence after audit_log_filter_set_filter(), and post-flush session behavior are covered under audit_log_filter_flush() and Persistence and refreshing in Audit log filter functions, options, and variables.

Filter modification lifecycle

The diagram below shows how filter changes persist, reload into the component, and reach sessions (including when audit_log_filter_flush() runs).

Audit Log Filter modification lifecycle

Constraints

Enable the component_audit_log_filter component and ensure audit tables exist before calling audit log filter functions. The account must hold the required privileges.

Filter definition validation

Introduced in Percona Server for MySQL 8.4.9-9.

The server validates filter definitions at parse time and rejects invalid input with a clear error:

  • Unknown field names (e.g., "WRONG.str")

  • Invalid class or event subclass names

  • Empty arrays (e.g., "class": [])

  • Unknown JSON keys

  • print rules that reference invalid fields for any class in a multi-class array

  • Mismatched field types (e.g., negative values for unsigned fields, integers where only strings are allowed)

An empty filter object {} is equivalent to {"filter": {"log": true}} and logs every event. To log nothing, use {"filter": {"log": false}}.

Parse-phase subclass names must use preparse and postparse.

audit_log_filter.event_mode controls which classes new definitions may use; filters saved under FULL can still load under REDUCED with some classes skipped (see that variable).

Using the audit log filter functions

Assignment vs rules inside the JSON

Two mechanisms apply, in order:

  1. Assignment (mysql.audit_log_user) — Each session uses one named filter from the USER and HOST columns (the same user_name@host_name form you pass to audit_log_filter_set_user()). The server loads that filter’s JSON from mysql.audit_log_filter. Assignments do not merge: a session never evaluates two separate filter definitions at once.

  2. Rules inside the assigned JSON — log conditions on a class or event block narrow which events match within the already-selected filter. Conditions compare event fields (such as user.str, host.str, table_database.str, table_name.str, status) with field items, and combine them with and / or / not. They are not a second user- or host-level assignment row. For example, bind one filter to 'app'@'%' and still include a log condition under a connection rule so only connection events from chosen client hosts are logged.

See Test event field values and Combine conditions with logical operators for the grammar used in rule-level conditions.

Which audit_log_user row applies

On connect, the component selects a row in mysql.audit_log_user whose USER and HOST match the session account. Literal user@host pairs match when they equal the session identity. Starting in Percona Server for MySQL 8.4.4, wildcard characters (% and _) are allowed in the host portion of the assignment string (see audit_log_filter_set_user()); pattern matching matches the behavior when you create the row through that function.

Keep assignments non-overlapping when you use wildcards. If several rows could match one connection, precedence is not specified here—prefer explicit literal user@host rows (or one clear pattern plus a '%' default) and confirm behavior on a test server.

With no matching row, the component uses the default assignment: the account registered with audit_log_filter_set_user() using % as the user name (see audit_log_filter_set_user()).

If neither a matching row nor a default exists, the component skips event processing for that connection.

A specific account row overrides the default: if both admin@localhost and % have filters, admin from localhost uses the admin@localhost filter, not the default.

You can bind filters to named accounts or remove those bindings.

To clear a binding, unassign the filter or assign a different one. How sessions refresh when assignments change is described under audit_log_filter_set_user() and audit_log_filter_remove_filter().

set_filter options and available filters

JSON layout (filter, class, nested rules, examples) is in Write audit_log_filter definitions. The authoritative list of class names, event subclass names, and per-class field names that audit_log_filter_set_filter() accepts appears in Audit Log Filter definition fields. This section lists the keys that may appear at each level of a filter definition.

Filter-level keys

Key Role
log Boolean global default. true enables logging everywhere not turned off by a more specific rule; false requires per-class/per-event log overrides to write anything.
class One class block or an array of class blocks. Each block sets "name" to an event class (general, connection, table_access, message; plus global_variable, command, query, stored_program, authentication, parse when event_mode=FULL).
id Optional filter identifier. Referenced by activate / ref when one filter swaps itself for another mid-session (see Replace a filter dynamically).

Class-block keys

Key Role
name The class name (see above).
log Optional. Boolean, or a condition that narrows matches by event-field values.
event Optional. One event block or an array. Each block names one subclass and can carry its own log, abort, print, or nested filter. Subclasses depend on the class — for table_access: read, insert, update, delete; for connection: connect, disconnect, change_user (plus pre_authenticate in FULL). See the event and subclass table and definition fields.
print Optional. Field-replacement rule. Currently limited to replacing general_query.str / query.str with query_digest — see Redact audit log fields.

Event-block keys

Key Role
name Subclass name. May be a string (one subclass) or an array (several).
log Optional. Boolean, or a condition over event fields.
abort Optional. Boolean or condition that blocks execution of matching statements — see Block statements with an audit log filter.
print Optional. Field-replacement rule scoped to this event — see Redact audit log fields.
filter Optional. Nested subfilter used with activate / ref for dynamic filter swapping — see Replace a filter dynamically.

Conditions

log and abort accept a Boolean (true / false) or a condition built from these items:

Item Role
field { "name": "<event-field>", "value": <value> }. Compares an event field such as user.str, host.str, table_database.str, table_name.str, status, general_command.str, or general_sql_command.str. Per-class fields are listed in Audit Log Filter definition fields.
variable { "name": "<server-variable>", "value": <value> }. Compares a predefined variable such as audit_log_connection_policy_value.
function { "name": "<function>", "args": [...] }. Calls a built-in such as find_in_include_list, string_find, or query_digest.
and Array of sub-conditions; all must be true.
or Array of sub-conditions; at least one must be true.
not A single sub-condition; true when the inner evaluates to false.

Field-value typing (JSON numbers for integer fields such as status, strings for *.str fields, and "::tcp/ip"-style symbolic constants for connection_type) is covered under audit_log_filter_set_filter() and in the connection section of Audit Log Filter definition fields.

Examples

Start from a single-class filter that logs every connection event the component sees:

SELECT audit_log_filter_set_filter('log_connection', '{
  "filter": {
    "class": { "name": "connection" }
  }
}');

Narrow to a single subclass by nesting event inside the class block (not as a sibling of class):

SELECT audit_log_filter_set_filter('log_connect_only', '{
  "filter": {
    "class": {
      "name": "connection",
      "event": { "name": "connect" }
    }
  }
}');

Narrow further by adding a log condition that tests event fields — here, log connect events from only two accounts, originating from one host:

SELECT audit_log_filter_set_filter('log_admin_connect', '{
  "filter": {
    "class": {
      "name": "connection",
      "event": {
        "name": "connect",
        "log": {
          "and": [
            { "field": { "name": "user.str", "value": ["admin", "developer"] } },
            { "field": { "name": "host.str", "value": "10.0.0.5" } }
          ]
        }
      }
    }
  }
}');

For full authoring detail, see:

Additional reading