Back-End

13 jun, 2013

Logando as queries do Magento e rastreando seus problemas

Publicidade

O artigo de hoje diz respeito a como logar todas as queries do Magento. Existem muitas formas de fazer isso, mas a mais simples e “bonitinha” que vi até o momento é alterando algumas variáveis do arquivo lib/varien/Db/Adapter/Pdo/Mysql.php (a partir do Magento 1.4).

protected $_debug               = true;
protected $_logAllQueries       = true;

E, por fim, especifique o caminho e a pasta do arquivo onde serão gravadas, bem como certifique-se de dar permissões de escrita no arquivo/pasta.

protected $_debugFile  = 'var/debug/sql.txt';

Lembre-se: jamais altere um arquivo da lib ou do core do Magento, exceto para fins de debug. Volte ao valor padrão assim que possível.

Fazendo backtrace dos erros de SQL no Magento

Se apenas exibir as queries não for suficiente para descobrir a origem de algum erro, há ainda uma outra abordagem bem interessante: logar o backtrace do objeto Varien_Debug durante a exception.

Para isso iremos alterar temporariamente dois arquivos.

Para logar erros de queries simples, no app/code/local/Zend/Db/Adapter/Pdo/Abstract.php, localize o método query() e adicione o trecho em destaque no catch do try, como mostrado abaixo:

public function query($sql, $bind = array())
{
if (empty($bind) && $sql instanceof Zend_Db_Select) {
$bind = $sql->getBind();
}

if (is_array($bind)) {
foreach ($bind as $name => $value) {
if (!is_int($name) && !preg_match('/^:/', $name)) {
$newName = ":$name";
unset($bind[$name]);
$bind[$newName] = $value;
}
}
}

try {
return parent::query($sql, $bind);
} catch (PDOException $e) {
/**
* @see Zend_Db_Statement_Exception
*/
#require_once 'Zend/Db/Statement/Exception.php';

// NOSSO BACKTRACE
Mage::log("[error] => {$e->getMessage()} \n
[query] => {$sql} \n
[backtrace] => ". Varien_Debug::backtrace(true, false) . "\n\n",
Zend_Log::ERR, 'martins.log', true);
// FIM DO NOSSO BACKTRACE
throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);
}
}

Em seguida, procure o arquivo lib/Zend/Db/Statement/Pdo.php e adicione este outro trecho no método _execute() para exibir erros de queries transacionais.

public function _execute(array $params = null)
{
try {
if ($params !== null) {
return $this->_stmt->execute($params);
} else {
return $this->_stmt->execute();
}
} catch (PDOException $e) {
#require_once 'Zend/Db/Statement/Exception.php';

// NOSSO BACKTRACE
Mage::log("[error] => {$e->getMessage()} \n
[statement] => {$this->_stmt->queryString} \n
[backtrace] => ". Varien_Debug::backtrace(true, false) . "\n\n",
Zend_Log::ERR, 'martins.log', true);
// FIM DO NOSSO BACKTRACE
throw new Zend_Db_Statement_Exception($e->getMessage(), (int) $e->getCode(), $e);
}
}

Isso deve ajudá-lo a debugar e localizar erros de sql causados por alguns módulos e até mesmo pelo próprio Magento. Nesse caso, o arquivo martins.log será criado em var/log.

Referência
Stack Overflow
Apresentação do Erick Hansen (Classy Llama) –  (Link direto do Download)