CakePHPではデバッグレベルが2の場合、レンダリングした画面の下部に発行したSQLのログを表示してくれます。

この機能は非常に便利ですが、本番環境などでデバッグレベルを0にしていると、発行したSQLを確認する手段がありません。

本番環境で何かしらデータベースエラーが発生した場合に、発行されているSQLを確認したいと思っても、そのままでは方法が無いのが現状です。

そこで、利用しているデータベースのドライバクラスを改良して、CakePHPのデバッグレベルに関わらず、発行したSQLをログファイルに保存できるように改造してみます。

ロギング用のデータベースドライバを作成

CakePHPのコアファイルに手を入れるのは避けたいので、データベースのドライバクラスを継承したログファイル保存用のドライバクラスを作成します。

ここではMySQLを利用する場合を想定します。
他のデータベースを利用している場合は、適宜利用しているデータベースのドライバクラスにを読み替えて下さい。

ファイルを作成

app/models/datasources/dbo_mysql_log.php を作成します。

dbo_mysqlを継承したコードを記述する

ここではDboMysqlを継承したDboMysqlLogという名前でクラスを作成します。

そして、SQLを発行するための関数であるexecute関数と、SQLのログ表示に関する処理を行うlogQuery関数をオーバーライトして、SQLをログに保存する設定であれば、実行したSQLをログファイルに保存できるように改良します。

App::import()関数を利用してスーパークラスを読み込んでおかないとエラーが出ますので注意して下さい。

データベースの接続設定を行う

app/configs/database.php ファイルの中で、利用するデータベースのドライバ指定を、先ほど作成したドライバに切り替えます。

public $development = array(
	'driver' => 'mysql_log',
	'persistent' => false,
	'host' => 'localhost',
	'login' => '********',
	'password' => '********',
	'database' => 'test',
	'prefix' => '',
	'encoding' => 'utf8'
);

driverの指定は、作成したドライバのファイル名から dbo_ と拡張子を除いたもので指定しましょう。

ログ保存用の設定を行う

config/bootstrap.php に下記のようなコードを記述します。

Configure::write('Sql.log', true);

これで、デバッグレベルに関係なく、発行されたSQLが tmp/logs/sql.log に出力されます。