MySQL道普請便り

第219回MySQLエラーログの出力形式をカスタマイズする

MySQL 8.0以降、エラーログの管理は「エラーログコンポーネント」という新しいアーキテクチャを採用しています。このシステムは、エラーログイベントのフィルタリングを担当する「エラーログフィルターコンポーネント」と、エラーログイベントの出力を担当する「エラーログシンクコンポーネント(ライター⁠⁠」の2つの主要部分に分けられます。

以前の第155回では、エラーログのフィルタリングに焦点を当て、ログイベントのフィルタリングに特化したコンポーネントの概要を紹介しました。今回は、その続編として「エラーログシンクコンポーネント」にスポットライトを当て、このコンポーネントを使うとことでどのような出力ができるのか見ていきましょう。なお、この記事で取り上げるMySQLのバージョンは8.0.35になります。

エラーログ出力形式の確認

現在設定しているエラーログコンポーネントは、log_error_servicesで確認することができます。

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

ここでは、log_filter_internalはエラーログフィルターコンポーネント部分で、log_sink_internalがエラーログシンクコンポーネントになります。

また、バージョン8.0.14以降、起動時等にエラーログの設定を判定する前に出力されるログイベントは一度バッファし、判定後にログイベントを遡って設定の形式で出力するようになりました(ただし、ログの設定を判定する前に致命的なエラーが発生した場合はデフォルトの設定のまま出力されます⁠⁠。この変更によって、より統一された形式でログを出力することが可能になっています。

詳細については、こちらのワークログ(#WL11875)をご確認ください。

エラーログ設定方法

エラーログの設定には、設定ファイル(my.cnf)に記述する暗黙的な方法と、INSTALL COMPONENTコマンドを実行する明示的な方法の2種類があります。暗黙的な設定方法はバージョン8.0.30で追加され、これによりInnoDBストレージエンジンの起動よりも前にlog_error_servicesがロードされるため、システム起動の初期段階からエラーログシステムを利用できるようになります。

この記事ではログ出力をJSON形式に変更するために、log_sink_jsonを使用する暗黙的な設定方法について説明します。

暗黙的な方法での設定

暗黙的な設定方法のやり方ではmy.cnfにlog_error_servicesを設定し、再起動します。

[mysqld]
log_error_services='log_filter_internal; log_sink_json'

必要であれば、SET PERSISTを使ってlog_error_servicesを永続化しておきましょう。

SET PERSIST log_error_services = 'log_filter_internal; log_sink_json';

log_sinkの組み合わせ

エラーログシンクコンポーネントは、1つだけでなく複数を組み合わせて使用することが可能です。たとえば、デフォルトのlog_sink_internalと、JSON形式で出力するlog_sink_jsonを同時に設定することで、標準のエラーログに加えてJSON形式でのログ出力も行えます。

mysql> SET PERSIST log_error_services = 'log_filter_internal; log_sink_internal; log_sink_json';

log_timestamps

エラーログに関連するシステム変数としてlog_timestampsというものがあります。このシステム変数は、ログに書き込まれるメッセージのタイムスタンプのタイムゾーンを制御します。ログシンクに到達する前にlog_timestampsをエラーイベントに適用するため、すべてのシンクのエラーメッセージ出力に影響します。

許可される値はUTC (デフォルト) とSYSTEM (ローカルシステムのタイムゾーン) となっています。

エラーログシンクコンポーネント

ここでは関連するエラーログシンクコンポーネントを紹介します。

log_sink_internal

log_sink_internalは、MySQLにおけるデフォルトのエラーログシンクコンポーネントです。このコンポーネントが有効になっている場合、ログの出力形式は time thread [label] [err_code] [subsystem] msgの形式で表示されます。ここで、[label]にはログレベルが含まれ、log_filter_internalの設定に基づいて、この特定の形式でログが出力されます。

2024-04-02T19:50:50.644588+09:00 0 [Note] [MY-011025] [Repl] Failed to start replica threads for channel ''.
2024-04-02T19:50:50.647810+09:00 0 [Note] [MY-011240] [Server] Plugin mysqlx reported: 'Using SSL configuration from MySQL Server'
2024-04-02T19:50:50.648018+09:00 5 [Note] [MY-010051] [Server] Event Scheduler: scheduler thread started with id 5
2024-04-02T19:50:50.651829+09:00 0 [Note] [MY-011243] [Server] Plugin mysqlx reported: 'Using OpenSSL for TLS connections'
2024-04-02T19:50:50.652031+09:00 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /tmp/mysqlx.sock

log_sink_syseventlog

log_sink_syseventlogはエラーログをシステムログ(Windowsの場合はイベントログ、Linuxの場合はsyslog)に出力します。ここではLinuxを例に紹介します。

/var/log/messages
Apr  2 19:57:39 db01 mysqld[15870]: Plugin mysqlx reported: 'Using SSL configuration from MySQL Server'
Apr  2 19:57:39 db01 mysqld[15870]: Plugin mysqlx reported: 'Using OpenSSL for TLS connections'
Apr  2 19:57:39 db01 mysqld[15870]: /usr/local/mysql8035/bin/mysqld: ready for connections. Version: '8.0.35'  socket: '/tmp/mysql.sock'  port: 3306  MySQL Community Server - GPL.
Apr  2 19:57:39 db01 mysqld[15870]: Admin interface ready for connections, address: '127.0.0.1'  port: 33062
Apr  2 19:57:39 db01 mysqld[15870]: X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /tmp/mysqlx.sock

このエラーログコンポーネントに関連するシステム変数は3つあります。

syseventlog.facility
syslogのファシリティを指定します。デフォルトはdaemonになっています。
syseventlog.include_pid
出力時にプロセスIDを含めるかどうかを指定します。
syseventlog.tag
syslogに出力するときにタグを設定できます。デフォルトは空文字で、設定すると先頭にハイフンが付いたタグが追加されます。
mysql> SELECT @@syseventlog.tag, @@syseventlog.facility, @@syseventlog.include_pid;
+-------------------+------------------------+---------------------------+
| @@syseventlog.tag | @@syseventlog.facility | @@syseventlog.include_pid |
+-------------------+------------------------+---------------------------+
|                   | daemon                 |                         1 |
+-------------------+------------------------+---------------------------+
1 row in set (0.00 sec)

log_sink_json

log_sink_jsonはJSON形式でエラーログを出力します。出力先はシステム変数log_errorにあるファイル名に番号.jsonをつけたファイルに出力されます。出力内容はlog_sink_internalの項目にプラスしてtsやsource_fileなどが追加で表示されます。

出力ファイルをjqで表示
$ error.log | jq
~ 
{
  "prio": 0,
  "err_code": 11323,
  "component": "mysqlx",
  "source_line": 287,
  "source_file": "socket_acceptors_task.cc",
  "function": "show_startup_log",
  "msg": "X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /tmp/mysqlx.sock",
  "time": "2024-04-02T20:13:07.237254+09:00",
  "ts": 1712056387237,
  "err_symbol": "ER_XPLUGIN_LISTENER_STATUS_MSG",
  "SQL_state": "HY000",
  "subsystem": "Server",
  "label": "System"
}
{
  "prio": 2,
  "err_code": 13360,
  "component": "plugin:mysql_native_password",
  "subsystem": "Server",
  "source_file": "sql_authentication.cc",
  "function": "native_password_authentication_deprecation_warning",
  "msg": "Plugin mysql_native_password reported: ''mysql_native_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'",
  "time": "2024-04-02T20:20:28.265119+09:00",
  "ts": 1712056828265,
  "thread": 8,
  "err_symbol": "ER_SERVER_WARN_DEPRECATED",
  "SQL_state": "HY000",
  "label": "Warning"
}

まとめ

今回はMySQLのエラーログに関連する重要な機能の1つ、エラーログシンクコンポーネントに焦点を当てました。この機能を活用することで、ログ出力をJSON形式やsyslogに統一し、他のシステムとの連携を容易にすることが可能です。日常的に設定を変更することは少ないかもしれませんが、このような柔軟性があることを知っておくことは大切です。

エラーログシンクコンポーネントの詳細については、MySQLの公式ドキュメントにて詳しく解説されていますので、設定時にはぜひ参考にしてみてください。

おすすめ記事

記事・ニュース一覧