6.4.5.8 Writing Audit Log Filter Definitions

Filter definitions are JSON values. For information about using JSON data in MySQL, see Section 11.5, “The JSON Data Type”.

Filter definitions have this form, where actions indicates how filtering takes place:

{ "filter": actions }

The following discussion describes permitted constructs in filter definitions.

Logging All Events

To explicitly enable or disable logging of all events, use a log element in the filter:

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

The log value can be either true or false.

The preceding filter enables logging of all events. It is equivalent to:

{
  "filter": { }
}

Logging behavior depends on the log value and whether class or event items are specified:

  • With log specified, its given value is used.

  • Without log specified, logging is true if no class or event item is specified, and false otherwise (in which case, class or event can include their own log item).

Logging Specific Event Classes

To log events of a specific class, use a class element in the filter, with its name field denoting the name of the class to log:

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

The name value can be connection, general, or table_access to log connection, general, or table-access events, respectively.

The preceding filter enables logging of events in the connection class. It is equivalent to the following filter with log items made explicit:

{
  "filter": {
    "log": false,
    "class": { "log": true,
               "name": "connection" }
  }
}

To enable logging of multiple classes, define the class value as a JSON array element that names the classes:

{
  "filter": {
    "class": [
      { "name": "connection" },
      { "name": "general" },
      { "name": "table_access" }
    ]
  }
}
Note注意

When multiple instances of a given item appear at the same level within a filter definition, the item values can be combined into a single instance of that item within an array value. The preceding definition can be written like this:

{
  "filter": {
    "class": [
      { "name": [ "connection", "general", "table_access" ] }
    ]
  }
}
Logging Specific Event Subclasses

To select specific event subclasses, use an event item containing a name item that names the subclasses. The default action for events selected by an event item is to log them. For example, this filter enables logging for the named event subclasses:

{
  "filter": {
    "class": [
      {
        "name": "connection",
        "event": [
          { "name": "connect" },
          { "name": "disconnect" }
        ]
      },
      { "name": "general" },
      {
        "name": "table_access",
        "event": [
          { "name": "insert" },
          { "name": "delete" },
          { "name": "update" }
        ]
      }
    ]
  }
}

The event item can also contain explicit log items to indicate whether to log qualifying events. This event item selects multiple events and explicitly indicates logging behavior for them:

"event": [
  { "name": "read", "log": false },
  { "name": "insert", "log": true },
  { "name": "delete", "log": true },
  { "name": "update", "log": true }
]

The event item can also indicate whether to block qualifying events, if it contains an abort item. For details, see Blocking Execution of Specific Events.

Table 6.29, “Event Class and Subclass Combinations” describes the permitted subclass values for each event class.

Table 6.29 Event Class and Subclass Combinations

Event ClassEvent SubclassDescription
connectionconnectConnection initiation (successful or unsuccessful)
connectionchange_userUser re-authentication with different user/password during session
connectiondisconnectConnection termination
generalstatusGeneral operation information
messageinternalInternally generated message
messageuserMessage generated by audit_api_message_emit_udf()
table_accessreadTable read statements, such as SELECT or INSERT INTO ... SELECT
table_accessdeleteTable delete statements, such as DELETE or TRUNCATE TABLE
table_accessinsertTable insert statements, such as INSERT or REPLACE
table_accessupdateTable update statements, such as UPDATE

Table 6.30, “Log and Abort Characteristics Per Event Class and Subclass Combination” describes for each event subclass whether it can be logged or aborted.

Table 6.30 Log and Abort Characteristics Per Event Class and Subclass Combination

Event ClassEvent SubclassCan be LoggedCan be Aborted
connectionconnectYesNo
connectionchange_userYesNo
connectiondisconnectYesNo
generalstatusYesNo
messageinternalYesYes
messageuserYesYes
table_accessreadYesYes
table_accessdeleteYesYes
table_accessinsertYesYes
table_accessupdateYesYes

Inclusive and Exclusive Logging

A filter can be defined in inclusive or exclusive mode:

  • Inclusive mode logs only explicitly specified items.

  • Exclusive mode logs everything but explicitly specified items.

To perform inclusive logging, disable logging globally and enable logging for specific classes. This filter logs connect and disconnect events in the connection class, and events in the general class:

{
  "filter": {
    "log": false,
    "class": [
      {
        "name": "connection",
        "event": [
          { "name": "connect", "log": true },
          { "name": "disconnect", "log": true }
        ]
      },
      { "name": "general", "log": true }
    ]
  }
}

To perform exclusive logging, enable logging globally and disable logging for specific classes. This filter logs everything except events in the general class:

{
  "filter": {
    "log": true,
    "class":
      { "name": "general", "log": false }
  }
}

This filter logs change_user events in the connection class, message events, and table_access events, by virtue of not logging everything else:

{
  "filter": {
    "log": true,
    "class": [
      {
        "name": "connection",
        "event": [
          { "name": "connect", "log": false },
          { "name": "disconnect", "log": false }
        ]
      },
      { "name": "general", "log": false }
    ]
  }
}
Testing Event Field Values

To enable logging based on specific event field values, specify a field item within the log item that indicates the field name and its expected value:

{
  "filter": {
    "class": {
    "name": "general",
      "event": {
        "name": "status",
        "log": {
          "field": { "name": "general_command.str", "value": "Query" }
        }
      }
    }
  }
}

Each event contains event class-specific fields that can be accessed from within a filter to perform custom filtering.

A connection event indicates when a connection-related activity occurs during a session, such as a user connecting to or disconnecting from the server. Table 6.31, “Connection Event Fields” indicates the permitted fields for connection events.

Table 6.31 Connection Event Fields

Field NameField TypeDescription
statusinteger

Event status:

0: OK

Otherwise: Failed

connection_idunsigned integerConnection ID
user.strstringUser name specified during authentication
user.lengthunsigned integerUser name length
priv_user.strstringAuthenticated user name (account user name)
priv_user.lengthunsigned integerAuthenticated user name length
external_user.strstringExternal user name (provided by third-party authentication plugin)
external_user.lengthunsigned integerExternal user name length
proxy_user.strstringProxy user name
proxy_user.lengthunsigned integerProxy user name length
host.strstringConnected user host
host.lengthunsigned integerConnected user host length
ip.strstringConnected user IP address
ip.lengthunsigned integerConnected user IP address length
database.strstringDatabase name specified at connect time
database.lengthunsigned integerDatabase name length
connection_typeinteger

Connection type:

or "::undefined": Undefined

or "::tcp/ip": TCP/IP

or "::socket": Socket

or "::named_pipe": Named pipe

or "::ssl": TCP/IP with encryption

or "::shared_memory": Shared memory


The "::xxx" values are symbolic pseudo-constants that may be given instead of the literal numeric values. They must be quoted as strings and are case-sensitive.

A general event indicates the status code of an operation and its details. Table 6.32, “General Event Fields” indicates the permitted fields for general events.

Table 6.32 General Event Fields

Field NameField TypeDescription
general_error_codeinteger

Event status:

0: OK

Otherwise: Failed

general_thread_idunsigned integerConnection/thread ID
general_user.strstringUser name specified during authentication
general_user.lengthunsigned integerUser name length
general_command.strstringCommand name
general_command.lengthunsigned integerCommand name length
general_query.strstringSQL statement text
general_query.lengthunsigned integerSQL statement text length
general_host.strstringHost name
general_host.lengthunsigned integerHost name length
general_sql_command.strstringSQL command type name
general_sql_command.lengthunsigned integerSQL command type name length
general_external_user.strstringExternal user name (provided by third-party authentication plugin)
general_external_user.lengthunsigned integerExternal user name length
general_ip.strstringConnected user IP address
general_ip.lengthunsigned integerConnection user IP address length

general_command.str indicates a command name: Query, Execute, Quit, or Change user.

A general event with the general_command.str field set to Query or Execute contains general_sql_command.str set to a value that specifies the type of SQL command: alter_db, alter_db_upgrade, admin_commands, and so forth. These values can be seen as the last components of the Performance Schema instruments displayed by this statement:

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            |
...

A table-access event provides information about specific table accesses. Table 6.33, “Table-Access Event Fields” indicates the permitted fields for table-access events.

Table 6.33 Table-Access Event Fields

Field NameField TypeDescription
connection_idunsigned integerEvent connection ID
sql_command_idintegerSQL command ID
query.strstringSQL statement text
query.lengthunsigned integerSQL statement text length
table_database.strstringDatabase name associated with event
table_database.lengthunsigned integerDatabase name length
table_name.strstringTable name associated with event
table_name.lengthunsigned integerTable name length

The following list shows which statements produce which table-access events:

  • read event:

    • SELECT

    • INSERT ... SELECT (for tables referenced in SELECT clause)

    • REPLACE ... SELECT (for tables referenced in SELECT clause)

    • UPDATE ... WHERE (for tables referenced in WHERE clause)

    • HANDLER ... READ

  • delete event:

    • DELETE

    • TRUNCATE TABLE

  • insert event:

    • INSERT

    • INSERT ... SELECT (for table referenced in INSERT clause)

    • REPLACE

    • REPLACE ... SELECT (for table referenced in REPLACE clause

    • LOAD DATA

    • LOAD XML

  • update event:

    • UPDATE

    • UPDATE ... WHERE (for tables referenced in UPDATE clause)

Blocking Execution of Specific Events

event items can include an abort item that indicates whether to prevent qualifying events from executing. For example, abort enables rules to be written that block execution of specific SQL statements.

The abort item must appear within an event item. For example:

"event": {
  "name": qualifying event subclass names
  "abort": condition
}

For event subclasses selected by the name item, the abort action is true or false, depending on condition evaluation. If the condition evaluates to true, the event is blocked. Otherwise, the event continues executing.

The condition specification can be as simple as true or false, or it can be more complex such that evaluation depends on event characteristics.

This filter blocks INSERT, UPDATE, and DELETE statements:

{
  "filter": {
    "class": {
      "name": "table_access",
      "event": {
        "name": [ "insert", "update", "delete" ],
        "abort": true
      }
    }
  }
}

This more complex filter blocks the same statements, but only for a specific table (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" } }
          ]
        }
      }
    }
  }
}

Statements matched and blocked by the filter return an error to the client:

ERROR 1045 (28000): Statement was aborted by an audit log filter

Not all events can be blocked (see Table 6.30, “Log and Abort Characteristics Per Event Class and Subclass Combination”). For an event that cannot, the audit log writes a warning to the error log rather than blocking it.

For attempts to define a filter in which the abort item appears elsewhere than in an event item, an error occurs.

Logical Operators

Logical operators (and, or, not) can be used in log items. This permits construction of more advanced filtering configurations:

{
  "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 } }
              ]
            }
          ]
        }
      }
    }
  }
}
Referencing Predefined Variables

To refer to a predefined variable in a log condition, use a variable item, which tests equality against a given value:

{
  "filter": {
    "class": {
      "name": "general",
      "event": {
        "name": "status",
        "log": {
          "variable": {
            "name": "audit_log_connection_policy_value", "value": "::none"
          }
        }
      }
    }
  }
}

Each predefined variable corresponds to a system variable. By writing a filter that tests a predefined variable, you can modify filter operation by setting the corresponding system variable, without having to redefine the filter. For example, by writing a filter that tests the value of the audit_log_connection_policy_value predefined variable, you can modify filter operation by changing the value of the audit_log_connection_policy system variable.

The audit_log_xxx_policy system variables are used for the legacy mode audit log (see Section 6.4.5.9, “Legacy Mode Audit Log Filtering”). With rule-based audit log filtering, those variables remain visible (for example, using SHOW VARIABLES), but changes to them have no effect unless you write filters containing constructs that refer to them.

The following list describes the permitted predefined variables for variable items:

  • audit_log_connection_policy_value

    This variable corresponds to the value of the audit_log_connection_policy system variable. The value is an unsigned integer. Table 6.34, “audit_log_connection_policy_value Values” shows the permitted values and the corresponding audit_log_connection_policy values.

    Table 6.34 audit_log_connection_policy_value Values

    ValueCorresponding audit_log_connection_policy Value
    0 or "::none"NONE
    1 or "::errors"ERRORS
    2 or "::all"ALL

    The "::xxx" values are symbolic pseudo-constants that may be given instead of the literal numeric values. They must be quoted as strings and are case-sensitive.

  • audit_log_policy_value

    This variable corresponds to the value of the audit_log_policy system variable. The value is an unsigned integer. Table 6.35, “audit_log_policy_value Values” shows the permitted values and the corresponding audit_log_policy values.

    Table 6.35 audit_log_policy_value Values

    ValueCorresponding audit_log_policy Value
    0 or "::none"NONE
    1 or "::logins"LOGINS
    2 or "::all"ALL
    3 or "::queries"QUERIES

    The "::xxx" values are symbolic pseudo-constants that may be given instead of the literal numeric values. They must be quoted as strings and are case-sensitive.

  • audit_log_statement_policy_value

    This variable corresponds to the value of the audit_log_statement_policy system variable. The value is an unsigned integer. Table 6.36, “audit_log_statement_policy_value Values” shows the permitted values and the corresponding audit_log_statement_policy values.

    Table 6.36 audit_log_statement_policy_value Values

    ValueCorresponding audit_log_statement_policy Value
    0 or "::none"NONE
    1 or "::errors"ERRORS
    2 or "::all"ALL

    The "::xxx" values are symbolic pseudo-constants that may be given instead of the literal numeric values. They must be quoted as strings and are case-sensitive.

Referencing Predefined Functions

To refer to a predefined function in a log condition, use a function item, which takes name and args values to specify the function name and its arguments, respectively:

{
  "filter": {
    "class": {
      "name": "general",
      "event": {
        "name": "status",
        "log": {
          "function": {
            "name": "find_in_include_list",
            "args": [ { "string": [ { "field": "user.str" },
                                    { "string": "@"},
                                    { "field": "host.str" } ] } ]
          }
        }
      }
    }
  }
}

The function as specified in the name item should be the function name only, without parentheses or the argument list. Arguments in the args item, if there is one, must be given in the order listed in the function description. Arguments can refer to predefined variables, event fields, or string or numeric constants.

The preceding filter determines whether to log general class status events depending on whether the current user is found in the audit_log_include_accounts system variable. That user is constructed using fields in the event.

The following list describes the permitted predefined functions for function items:

  • audit_log_exclude_accounts_is_null()

    Checks whether the audit_log_exclude_accounts system variable is NULL. This function can be helpful when defining filters that correspond to the legacy audit log implementation.

    Arguments:

    None.

  • audit_log_include_accounts_is_null()

    Checks whether the audit_log_include_accounts system variable is NULL. This function can be helpful when defining filters that correspond to the legacy audit log implementation.

    Arguments:

    None.

  • debug_sleep(millisec)

    Sleeps for the given number of milliseconds. This function is used during performance measurement.

    debug_sleep() is available for debug builds only.

    Arguments:

    • millisec: An unsigned integer that specifies the number of milliseconds to sleep.

  • find_in_exclude_list(account)

    Checks whether an account string exists in the audit log exclude list (the value of the audit_log_exclude_accounts system variable).

    Arguments:

    • account: A string that specifies the user account name.

  • find_in_include_list(account)

    Checks whether an account string exists in the audit log include list (the value of the audit_log_include_accounts system variable).

    Arguments:

    • account: A string that specifies the user account name.

  • string_find(text, substr)

    Checks whether the substr value is contained in the text value. This search is case-sensitive.

    Arguments:

    • text: The text string to search.

    • substr: The substring to search for in text.

Replacing a User Filter

In some cases, the filter definition can be changed dynamically. To do this, define a filter configuration within an existing filter. For example:

{
  "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" } }
            ]
          }
        }
      }
    }
  }
}

A new filter is activated when the activate element within a subfilter evaluates to true. Using activate in a top-level filter is not permitted.

A new filter can be replaced with the original one by using a ref item inside the subfilter to refer to the original filter id.

The filter shown operates like this:

  • The main filter waits for table_access events, either update or delete.

  • If the update or delete table_access event occurs on the temp_1 or temp_2 table, the filter is replaced with the internal one (without an id, since there is no need to refer to it explicitly).

  • If the end of the command is signalled (general / status event), an entry is written to the audit log file and the filter is replaced with the main filter.

The filter is useful to log statements that update or delete anything from the temp_1 or temp_2 tables, such as this one:

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

The statement generates multiple table_access events, but the audit log file contains only general / status entries.

Note注意

Any id values used in the definition are evaluated with respect only to that definition. They have nothing to do with the value of the audit_log_filter_id system variable.