Switching to JSON Error Logging in MySQL

Switching to JSON Error Logging in MySQL

You no longer need to manually parse the MySQL Error log via scripting and RegEx pattern matching. Using the component_log_sink_json component you can obtain JSON error logging for easier parsing.

See Installing MySQL 9.7 Community Edition on CentOS for my local Mac VM setup to duplicate these commands.

Traditional MySQL Error Log

$ ERROR_LOG=$(mysql -uroot -p${PASSWD} -AN -e "SELECT @@log_error")
$ sudo tail ${ERROR_LOG}

2026-06-18T16:17:30.945441Z 0 [Warning] [MY-011879] [InnoDB] Failed to set NUMA memory policy of buffer pool page frames with mbind(0xffff8fd1f000,137236480,MPOL_INTERLEAVE,...,...,MPOL_MF_MOVE) failed with Function not implemented
2026-06-18T16:17:30.947674Z 1 [Warning] [MY-011875] [InnoDB] Failed to set NUMA memory policy to MPOL_DEFAULT: Function not implemented
2026-06-18T16:17:31.043366Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2026-06-18T16:17:31.168296Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2026-06-18T16:17:31.168309Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2026-06-18T16:17:31.175996Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
2026-06-18T16:17:31.176000Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '9.7.1'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  MySQL Community Server - GPL.

JSON MySQL Error Log

To enable JSON logging, you install a component and make a configuration change. The before pre check state is:

mysql> SELECT * FROM mysql.component;
+--------------+--------------------+------------------------------------+
| component_id | component_group_id | component_urn                      |
+--------------+--------------------+------------------------------------+
|            1 |                  1 | file://component_validate_password |
+--------------+--------------------+------------------------------------+
1 row in set (0.002 sec)

mysql> SELECT @@log_error_services;
+----------------------------------------+
| @@log_error_services                   |
+----------------------------------------+
| log_filter_internal; log_sink_internal |
+----------------------------------------+
1 row in set (0.005 sec)

Install the JSON Sink Log Component (Available since 8.4).

mysql> INSTALL COMPONENT 'file://component_log_sink_json';
Query OK, 0 rows affected (0.028 sec)

mysql> SET PERSIST log_error_services = 'log_filter_internal; log_sink_json';
Query OK, 0 rows affected (0.014 sec)

mysql> SET GLOBAL log_error_verbosity=3;
Query OK, 0 rows affected (0.000 sec)

mysql> SELECT * FROM mysql.component;
+--------------+--------------------+------------------------------------+
| component_id | component_group_id | component_urn                      |
+--------------+--------------------+------------------------------------+
|            1 |                  1 | file://component_validate_password |
|            2 |                  2 | file://component_log_sink_json     |
+--------------+--------------------+------------------------------------+
2 rows in set (0.001 sec)

NOTE: We increase verbosity for demonstration purposes of logging onliy.

Validate JSON Logging

NOTE: To my knowledge there is no precise way to obtain the log file name. I’m sure lefred will throw me some special configuration setting to obtain this properly.

$ sudo tail -f ${ERROR_LOG}.00.json

Initially the file is empty, no conversion of existing logging, or a message indicating it is enabled.

Here are 3 simple ways to create different messages to verify logging is operational

# No password
$ mysql -uroot
# Invalid password
$  mysql -uroot -pinvalid
# Terminate connection 
mysql -uroot -p${PASSWD} &
kill -9 $!
$ sudo tail -f ${ERROR_LOG}.00.json
{ "prio" : 3, "err_code" : 10926, "component" : "sha256_password", "subsystem" : "Server", "source_file" : "sql_authentication.cc", "function" : "login_failed_error", "msg" : "Access denied for user 'root'@'localhost' (using password: NO)", "time" : "2026-06-18T16:47:42.581112Z", "ts" : 1781801262581, "thread" : 16, "err_symbol" : "ER_ACCESS_DENIED_ERROR_WITH_PASSWORD", "SQL_state" : "HY000", "label" : "Note" }
{ "prio" : 3, "err_code" : 10926, "component" : "sha256_password", "subsystem" : "Server", "source_file" : "sql_authentication.cc", "function" : "login_failed_error", "msg" : "Access denied for user 'root'@'localhost' (using password: YES)", "time" : "2026-06-18T16:47:47.424869Z", "ts" : 1781801267424, "thread" : 17, "err_symbol" : "ER_ACCESS_DENIED_ERROR_WITH_PASSWORD", "SQL_state" : "HY000", "label" : "Note" }
{ "prio" : 3, "err_code" : 10914, "subsystem" : "Server", "source_file" : "sql_connect.cc", "function" : "end_connection", "msg" : "Aborted connection 19 to db: 'unconnected' user: 'root' host: 'localhost' (Got an error reading communication packets).", "time" : "2026-06-18T16:48:53.776361Z", "ts" : 1781801333776, "thread" : 19, "err_symbol" : "ER_ABORTING_USER_CONNECTION", "SQL_state" : "HY000", "label" : "Note" }

Footnote: Extra mysql client precision

It has taken a good 10 years, but at least we have millisecond precision logging in mysql.

1 row in set (0.005 sec)
Tagged with: MySQL Logging JSON

Installing MySQL 9.7 LTS Community Edition on CentOS

Historically installing MySQL on a RedHat Compatible Linux server was as simple as yum install mysql-server. Today’s MySQL Oracle Linux, Red Hat Enterprise Linux, CentOS, and Fedora 9.7 instructions are not accurate mixing in 8.

Using GenAI directly in the database. A practical example using MySQL 8.0

If you have a typical MySQL production setup using MySQL 8.0 (EOL) with replication, you can take advantage of VillageSQL extensions to generate AI responses directly with your source data with no impact on your production setup or existing application software.

Producing Skewness statistics with SQL

Skewness measures the asymmetry of a distribution. A perfectly symmetric distribution has a skewness of zero. A positive skew (right-skewed) means the tail extends to the right — a small number of high values pull the mean above the median.