|
| 1 | +# Write Audit‑Log Filter definitions |
| 2 | + |
| 3 | +Percona Server’s audit‑log-filter plugin lets you control which events are recorded by supplying a JSON filter definition. |
| 4 | + |
| 5 | +A filter is stored in the `mysql.audit_log_filter` table and then attached to one or more MySQL accounts through the mysql.`audit_log_user` table. |
| 6 | + |
| 7 | +The following is a step‑by‑step guide that shows how to create a filter, attach it to a user, and verify that the desired events are captured or suppressed. |
| 8 | + |
| 9 | +## Filter JSON structure |
| 10 | + |
| 11 | +A filter consists of a top‑level object named `filter`. |
| 12 | + |
| 13 | +Inside this object you can set a global `log` flag and optionally define an array called `class`. |
| 14 | + |
| 15 | +Each element of the `class` array identifies a class name (for example, `connection`, `general`, `query`, `table_access`) and may contain an `event` object that specifies particular events and whether they should be logged. |
| 16 | + |
| 17 | +```json |
| 18 | +{ |
| 19 | + "filter": { |
| 20 | + "log": true, |
| 21 | + "class": [ |
| 22 | + { |
| 23 | + "name": "connection", |
| 24 | + "event": { |
| 25 | + "name": "connect", |
| 26 | + "log": true |
| 27 | + } |
| 28 | + }, |
| 29 | + { |
| 30 | + "name": "query", |
| 31 | + "event": { |
| 32 | + "name": "execute", |
| 33 | + "log": true |
| 34 | + } |
| 35 | + } |
| 36 | + ] |
| 37 | + } |
| 38 | +} |
| 39 | +``` |
| 40 | +If the `log` flag is omitted, the default value is `true`. |
| 41 | +When `log` is set to `false`, the filter disables logging for all statement‑type events unless a class entry overrides that setting. |
| 42 | + |
| 43 | +## Practical example |
| 44 | + |
| 45 | +Suppose you want a user named `excludeUserTest` to generate no audit records for statements, but the server should keep a generic record that a connection was established. |
| 46 | + |
| 47 | +First create a filter that disables logging globally: |
| 48 | + |
| 49 | +```{.bash data-prompt="mysql>"} |
| 50 | +mysql> INSERT INTO mysql.audit_log_filter (filter_id, name, filter) VALUES |
| 51 | +(1, 'log_none', |
| 52 | + '{"filter": {"log": false}}'); |
| 53 | +``` |
| 54 | + |
| 55 | +Ensure `filter_id` is unique; attempting to reuse an existing ID raises a duplicate-key error. |
| 56 | + |
| 57 | +Next map the filter to the user: |
| 58 | + |
| 59 | +```{.bash data-prompt="mysql>"} |
| 60 | +mysql> INSERT INTO mysql.audit_log_user (username, userhost, filtername) VALUES |
| 61 | +('excludeUserTest', '%', 'log_none'); |
| 62 | +``` |
| 63 | + |
| 64 | +After the insertion, reload the audit log filter plugin so the new configuration becomes active: |
| 65 | + |
| 66 | +```{.bash data-prompt="mysql>"} |
| 67 | +mysql> CALL mysql.audit_log_reload(); |
| 68 | +``` |
| 69 | + |
| 70 | +When `excludeUserTest` connects and runs queries, the audit log contains only the generic connection record that the plugin writes automatically. |
| 71 | + |
| 72 | +### Limitation – connection‑related events logged |
| 73 | + |
| 74 | +Even when a filter contains only ```{ "filter": { "log": false } }```, two kinds of audit records continue to appear: |
| 75 | + |
| 76 | +| Event | Class | When generated | |
| 77 | +|--------------------------|------------|--------------------------------------------------------------------------------| |
| 78 | +| pre_authenticate | connection | Before the server identifies the user. The default mapping (`% → log_all`) applies. | |
| 79 | +| general / log (status 0) | general | At session start. The filter does not disable the `general` class, so a record is written. | |
| 80 | + |
| 81 | +To prevent these records, create a filter that explicitly disables the `connection` and `general` classes and assign it to the user: |
| 82 | + |
| 83 | +```{.bash data-prompt="mysql>"} |
| 84 | +mysql> INSERT INTO mysql.audit_log_filter (filter_id, name, filter) VALUES |
| 85 | +(2, 'log_none_strict', |
| 86 | + '{ |
| 87 | + "filter": { |
| 88 | + "log": false, |
| 89 | + "class": [ |
| 90 | + {"name": "connection", "event": {"name": "pre_authenticate", "log": false}}, |
| 91 | + {"name": "general", "event": {"name": "log", "log": false}} |
| 92 | + ] |
| 93 | + } |
| 94 | + }'); |
| 95 | + |
| 96 | + |
| 97 | +mysql> UPDATE mysql.audit_log_user |
| 98 | + SET filtername = 'log_none_strict' |
| 99 | + WHERE username = 'excludeUserTest' AND userhost = '%'; |
| 100 | + |
| 101 | +mysql> CALL mysql.audit_log_reload(); |
| 102 | +``` |
| 103 | + |
| 104 | +After the reload, connections made by `excludeUserTest` will no longer generate the `pre_authenticate` or `general / log entries`. |
| 105 | + |
| 106 | +## View existing filters and mappings |
| 107 | + |
| 108 | +You can list the filters that are currently defined. |
| 109 | + |
| 110 | +```{.bash data-prompt="mysql>"} |
| 111 | +SELECT filter_id, name, filter FROM mysql.audit_log_filter; |
| 112 | +``` |
| 113 | + |
| 114 | +You can also list the user‑to‑filter mappings. |
| 115 | + |
| 116 | +```{.bash data-prompt="mysql>"} |
| 117 | +SELECT username, userhost, filtername FROM mysql.audit_log_user; |
| 118 | +``` |
| 119 | + |
| 120 | +These queries help you verify that the intended filter is attached to the correct accounts. |
| 121 | + |
| 122 | +## Verify the filter |
| 123 | + |
| 124 | +1. Rotate or remove the current audit log filter file so you can see fresh output. |
| 125 | + |
| 126 | +2. Connect to the server as `excludeUserTest` and run a simple query, for example, ```SELECT 1;```. |
| 127 | + |
| 128 | +3. Examine the audit log filter file (default location `/var/lib/mysql/audit.log`) with `tail -f /var/lib/mysql/audit.log`. |
| 129 | + |
| 130 | +4. Confirm that only the events you intended to keep appear. |
| 131 | + |
| 132 | +If unexpected events are still present, double‑check the JSON syntax, ensure the filter ID is unique, and verify that the reload statement succeeded without errors. |
| 133 | + |
| 134 | +## Troubleshoot and checklist |
| 135 | + |
| 136 | +* Define the JSON filter with the desired global `log` flag. |
| 137 | + |
| 138 | +* Add class entries for any event type that must be treated differently from the global setting. |
| 139 | + |
| 140 | +* Insert the filter into `mysql.audit_log_filter` with a unique `filter_id`. |
| 141 | + |
| 142 | +* Map the filter to the appropriate MySQL accounts in `mysql.audit_log_user`. |
| 143 | + |
| 144 | +* Reload the audit plugin to apply the changes. |
| 145 | + |
| 146 | +* Test the configuration with a fresh connection and inspect the audit log. |
| 147 | + |
| 148 | +This checklist ensures that the audit log filter records exactly the events you need while omitting unnecessary noise. |
0 commit comments