How to Debug Magento 2 an Adobe Commerce

The main areas to debug in Magento 2 and trace broken by default core functionality are:

Yegor Shytikov
3 min readJul 16, 2021
  • SQL queries /Models
  • Redis calls
  • Elastic Search Query bad performance
  • PHP execution

You can simply debug/log Magento 2 without writing any stupid Magento Plugin/Logger classes following these easy steps:

Log Magento SQL queries:

vendor/magento/framework/DB/Adapter/Pdo/Mysql.php:

*** Special handling for PDO query().** All bind parameter names must begin with ‘:’.** @param string|\Magento\Framework\DB\Select $sql The SQL statement with placeholders.* @param mixed $bind An array of data or data itself to bind to the placeholders.* @return \Zend_Db_Statement_Pdo|void* @throws \Zend_Db_Adapter_Exception To re-throw \PDOException.* @throws \Zend_Db_Statement_Exception* @SuppressWarnings(PHPMD.CyclomaticComplexity)*/protected function _query($sql, $bind = []){

Add there :

vendor/magento/framework/DB/Adapter/Pdo/Mysql.php                                                                        /*** Special handling for PDO query().** All bind parameter names must begin with ':'.** @param string|\Magento\Framework\DB\Select $sql The SQL statement with placeholders.* @param mixed $bind An array of data or data itself to bind to the placeholders.* @return \Zend_Db_Statement_Pdo|void* @throws \Zend_Db_Adapter_Exception To re-throw \PDOException.* @throws \Zend_Db_Statement_Exception* @SuppressWarnings(PHPMD.CyclomaticComplexity)*/protected function _query($sql, $bind = []){$connectionErrors = [2006, // SQLSTATE[HY000]: General error: 2006 MySQL server has gone away2013,  // SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query];$triesCount = 0;do {$retry = false;$this->logger->startTimer();try {$this->_checkDdlTransaction($sql);$this->_prepareQuery($sql, $bind);$result = parent::query($sql, $bind);

/// Add code From there -->>

echo " $sql " . " - > [" . implode(' - ', $bind) . "] <br> \n";$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,  0);foreach ($trace as $n => $t) { 
if ($n > 10 ) continue;
echo $t['file'] . "::" . $t['function'] . "<br> \n";
}

/// To there <<--

$this->logger->logStats(LoggerInterface::TYPE_QUERY, $sql, $bind, $result);return $result;} catch (\Exception $e) {

How To profile PHP.

To understand what's going on in PHP, you can use xDebug however it is too slow, you can use better solutions.

<?php
// Send notification through the server log
error_log(“My log message! $myVar”, 0);
// Notify by email if we run out of FOO
error_log(“Magento 2!”, 1, “magentosucks@magento.com”);
// another way to call error_log():
error_log(“You messed up!”, 3, “/var/tmp/my-errors.log”);

How To profile Redis Calls Issues:

Magento 2 is a bloated platform you should understand what MAgento caches a nd fetches al the time. I saw many times when magento cache something for the pages it don’t need. Cache should have low Cardinality and should be reused by many pages . If cache is unique per page it doesn’t have ANY sense…

A cache over a key with high cardinality will provide very small benefits, and may not be worth your trouble.

Remember that adding caching to a problem gets you two problems — make sure you got a real measurable benefit from importing that extra problem. Multidimensional keys are going to be necessary, but as you make a point of thinking about total latency, also make a point of mentally sizing up the key space.

vendor/magento/zendframework1/library/Zend/Cache/Core.phppublic function load($id, $doNotTestCacheValidity = false, $doNotUnserialize = false)

Add this lines:

$this->_log("Zend_Cache_Core: load item '{$id}'", 7);  
if(isset($_GET['redisTest']))
echo '^'.$id.'*';

in this way we can see when magento loadin and whot it is loading from the cache…

You can also add debug output to this method to check whats magento saving to the cache…

public function save($data, $id = null, $tags = array(), $specificLifetime = false, $priority = 8)

Improving:

You can envelop this code in the if condition:

if ($_GET['debug'] == "mysql"){ debug code }
if ($_GET['debug'] == "redis"){ debug code }
if ($_GET['debug'] == "elasticsearch"){ debug code }
if ($_GET['debug'] == "blocks"){ debug code }
if ($_GET['debug'] == "something"){ debug code }

Only with set GET[‘debug’] parameter you will see this output.

--

--

Yegor Shytikov
Yegor Shytikov

Written by Yegor Shytikov

True Stories about Magento 2. Melting down metal server infrastructure into cloud solutions.

No responses yet