2014年10月23日木曜日

CakePHP 2.xでSQLクエリーをログに出力する

おおよそ8か月ぶりの更新らしいです。
そこそこお仕事で忙しかったみたいです。Railsな案件→VBAな案件→CakePHPな案件と渡り歩いてます。

本題に移ると、まぁタイトルの通りなのですが、CakePHPでクエリのログをファイルに簡単に吐けないの?設定をチョロっといじるだけで出来たりしないの?と思い調べました。

結果としてちょっとしたコード書けば出来ることがわかったので書きました。
http://kwski.net/cakephp-2-x/1064/を参考にやれば終わりです。

だとエントリとしてちょっとあれなので、少しアレンジします。

参考サイトだとMySQLですが、今回対応したのはPostgreSQLです。でもやってることは同じです。
あと、クエリのみ出力と詳細出力を切り替えれるようにしてます。
MySQLの場合はPostgresになってるとこをMySQLに書き換えたら動くと思います。

1. カスタムしたdatasourceを作成

/app/Model/Datasource/Database/PostgresLog.phpのような名前で作成します。
名前は何でも良いです。
対象のdatasourceを継承したクラスを作ります。
<?php
App::uses('Postgres', 'Model/Datasource/Database');
class PostgresLog extends Postgres {
    function logQuery($sql, $params = array()) {
        parent::logQuery($sql);
        $logLevel = Configure::read('Cake.logQuery');
        switch ($logLevel):
        case 1:
            $this->log($sql, LOG_DEBUG);                // SQLクエリーのみ
            break;
        case 2:
            $this->log($this->_queriesLog, LOG_DEBUG);  // SQLの実行詳細
            break;
        endswitch;
    }
}
?>

2. 使用するdatasourceを変更

/app/Config/database.phpのdatasourceの指定を以下のように1で作成したクラスの名前に変更します。
        'datasource' => 'Database/Postgres',
        'datasource' => 'Database/PostgresLog',

3. 出力するフラグを設定

/app/Config/core.phpで以下のように設定します。1を指定するとSQLのみ、2を指定すると詳細、それ以外を指定するか、未指定だと出力しません。
    // クエリログを出力する(1: SQLのみ, 2: 詳細, other: なし)
    Configure::write('Cake.logQuery', 1);


と、こんな感じでコードを書いておくとデバッグが捗るんじゃないでしょうか。