Ignore:
Timestamp:
2012/03/04 04:20:00 (14 years ago)
Author:
Seasoft
Message:

#1633 (エラーハンドリングの改善)
#1676 (ログファイルを分離する)
#1677 (デバッグログの出力設定と画面へのエラー出力設定とを分離する)
#1678 (SQL の実行ログを提供する)
#1613 (typo修正・ソース整形・ソースコメントの改善)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/version-2_12-dev/data/class/SC_Query.php

    r21563 r21582  
    924924        $sth =& $this->conn->prepare($sql, $types, $result_types); 
    925925        if (PEAR::isError($sth)) { 
    926             if (!$this->force_run) { 
    927                 trigger_error($this->traceError($sth, $sql), E_USER_ERROR); 
    928             } else { 
    929                 error_log($this->traceError($sth, $sql), 3, LOG_REALFILE); 
    930             } 
     926            $msg = $this->traceError($sth, $sql); 
     927            $this->error($msg); 
    931928        } 
    932929        return $sth; 
     
    942939     */ 
    943940    function execute(&$sth, $arrVal = array()) { 
    944         $timeStart = SC_Utils_Ex::sfMicrotimeFloat(); 
     941 
     942        $arrStartInfo =& $this->lfStartDbTraceLog($sth, $arrVal); 
    945943        $affected =& $sth->execute((array)$arrVal); 
    946  
    947         // 一定以上時間かかったSQLの場合、ログ出力する。 
    948         if (defined('SQL_QUERY_LOG_MODE') && SQL_QUERY_LOG_MODE == true) { 
    949             $timeEnd = SC_Utils_Ex::sfMicrotimeFloat();; 
    950             $timeExecTime = $timeEnd - $timeStart; 
    951             if (defined('SQL_QUERY_LOG_MIN_EXEC_TIME') && $timeExecTime >= (float)SQL_QUERY_LOG_MIN_EXEC_TIME) { 
    952                 $logMsg = sprintf("SQL_LOG [%.2fsec]\n%s", $timeExecTime, $sth->query) . "\n"; 
    953                 error_log($logMsg, 3, LOG_REALFILE); 
    954             } 
    955         } 
     944        $this->lfEndDbTraceLog($arrStartInfo, $sth, $arrVal); 
    956945 
    957946        if (PEAR::isError($affected)) { 
    958947            $sql = isset($sth->query) ? $sth->query : ''; 
    959             if (!$this->force_run) { 
    960                 trigger_error($this->traceError($affected, $sql, $arrVal), E_USER_ERROR); 
    961             } else { 
    962                 error_log($this->traceError($affected, $sql, $arrVal), 3, LOG_REALFILE); 
    963             } 
     948            $msg = $this->traceError($affected, $sql, $arrVal); 
     949            $this->error($msg); 
    964950        } 
    965951        $this->conn->last_query = stripslashes($sth->query); 
     
    970956     * エラーの内容をトレースする. 
    971957     * 
     958     * XXX trigger_error で処理する場合、1024文字以内に抑える必要がある。 
     959     * XXX 重要な情報を先頭に置き、冗長になりすぎないように留意する。 
    972960     * @access private 
    973961     * @param PEAR::Error $error PEAR::Error インスタンス 
     
    977965     */ 
    978966    function traceError($error, $sql = '', $arrVal = false) { 
    979         $scheme = ''; 
    980         if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') { 
    981             $scheme = 'http://'; 
     967        $err = "SQL: [$sql]\n"; 
     968        if ($arrVal !== false) { 
     969            $err .= 'PlaceHolder: [' . var_export($arrVal, true) . "]\n"; 
     970        } 
     971        $err .= $error->getMessage() . "\n"; 
     972        $err .= rtrim($error->getUserInfo()) . "\n"; 
     973 
     974        // PEAR::MDB2 内部のスタックトレースを出力する場合、下記のコメントを外す。 
     975        // $err .= GC_Utils_Ex::toStringBacktrace($error->getBackTrace()); 
     976 
     977        return $err; 
     978    } 
     979 
     980    /** 
     981     * エラー処理 
     982     */ 
     983    function error($msg) { 
     984        $msg = "DB処理でエラーが発生しました。\n" . $msg; 
     985        if (!$this->force_run) { 
     986            trigger_error($msg, E_USER_ERROR); 
    982987        } else { 
    983             $scheme = 'https://'; 
    984         } 
    985  
    986         $err = $scheme . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "\n\n" 
    987             . 'SERVER_ADDR: ' . $_SERVER['SERVER_ADDR'] . "\n" 
    988             . 'REMOTE_ADDR: ' . $_SERVER['REMOTE_ADDR'] . "\n" 
    989             . 'USER_AGENT: ' . $_SERVER['HTTP_USER_AGENT'] . "\n\n" 
    990             . 'SQL: ' . $sql . "\n\n"; 
    991         if ($arrVal !== false) { 
    992             $err .= 'PlaceHolder: ' . var_export($arrVal, true) . "\n\n"; 
    993         } 
    994         $err .= $error->getMessage() . "\n\n"; 
    995         $err .= $error->getUserInfo() . "\n\n"; 
    996  
    997         $err .= SC_Utils_Ex::sfBacktraceToString($error->getBackTrace()); 
    998  
    999         return $err; 
     988            GC_Utils_Ex::gfPrintLog($msg, ERROR_LOG_REALFILE, true); 
     989        } 
    1000990    } 
    1001991 
     
    10301020    } 
    10311021 
     1022    /** 
     1023     * SQL の実行ログ (トレースログ) を書き出す 
     1024     * 
     1025     * @param string 実行するSQL文 
     1026     * @param array $arrVal プレースホルダに挿入する配列 
     1027     * @return void 
     1028     */ 
     1029    private function lfStartDbTraceLog(&$objSth, &$arrVal) { 
     1030        if (!defined('SQL_QUERY_LOG_MODE') || SQL_QUERY_LOG_MODE === 0) { 
     1031            return; 
     1032        } 
     1033        $arrInfo =& $GLOBALS['_SC_Query_TraceLogInfo']; 
     1034        if (!isset($arrInfo['http_request_id'])) { 
     1035            $arrInfo['http_request_id'] = uniqid(); 
     1036        } 
     1037 
     1038        $arrStartInfo = array( 
     1039            'http_request_id'   => $arrInfo['http_request_id'], 
     1040            'time_start'        => SC_Utils_Ex::sfMicrotimeFloat(), 
     1041            'count'             => ++$arrInfo['count'], 
     1042        ); 
     1043 
     1044        // ログモード1の場合、開始はログに出力しない 
     1045        if (SQL_QUERY_LOG_MODE === 1) { 
     1046            return $arrStartInfo; 
     1047        } 
     1048 
     1049        $msg = "[execute start {$arrStartInfo['http_request_id']}#{$arrStartInfo['count']}]\n" 
     1050             . 'SQL: ' . $objSth->query . "\n" 
     1051             . 'PlaceHolder: ' . var_export($arrVal, true) . "\n"; 
     1052        GC_Utils_Ex::gfPrintLog($msg, DB_LOG_REALFILE); 
     1053 
     1054        return $arrStartInfo; 
     1055    } 
     1056 
     1057    /** 
     1058     * SQL の実行ログ (トレースログ) を書き出す 
     1059     * 
     1060     * @param string 実行するSQL文 
     1061     * @param array $arrVal プレースホルダに挿入する配列 
     1062     * @return void 
     1063     */ 
     1064    private function lfEndDbTraceLog(&$arrStartInfo, &$objSth, &$arrVal) { 
     1065        if (!defined('SQL_QUERY_LOG_MODE') || SQL_QUERY_LOG_MODE === 0) { 
     1066            return; 
     1067        } 
     1068        $msg = "[execute end {$arrStartInfo['http_request_id']}#{$arrStartInfo['count']}]\n"; 
     1069 
     1070        $timeEnd = SC_Utils_Ex::sfMicrotimeFloat(); 
     1071        $timeExecTime = $timeEnd - $arrStartInfo['time_start']; 
     1072 
     1073        // ログモード1の場合、 
     1074        if (SQL_QUERY_LOG_MODE === 1) { 
     1075            // 規定時間より速い場合、ログに出力しない 
     1076            if (!defined('SQL_QUERY_LOG_MIN_EXEC_TIME') || $timeExecTime < (float)SQL_QUERY_LOG_MIN_EXEC_TIME) { 
     1077                return; 
     1078            } 
     1079            // 開始時にログ出力していないため、ここで実行内容を出力する 
     1080            $msg .= 'SQL: ' . $objSth->query . "\n"; 
     1081            $msg .= 'PlaceHolder: ' . var_export($arrVal, true) . "\n"; 
     1082        } 
     1083 
     1084        $msg .= 'execution time: ' . sprintf("%.2f sec", $timeExecTime) . "\n"; 
     1085        GC_Utils_Ex::gfPrintLog($msg, DB_LOG_REALFILE); 
     1086    } 
    10321087} 
Note: See TracChangeset for help on using the changeset viewer.