New Relic and Magento: Better Transaction Naming

New Relic supports Zend Framework out of the box.  Right?  Supposedly it does, but I didn’t get any useful information recorded when using Magento.  Everything came up “index.php”.

Unfortunately, getting a useful transaction name in New Relic from Magento requires modifying Magento core.  Fortunately, it’s a pretty simple modification.

For regular pageviews we’ll always have a module, controller, and action. But 3rd party scripts, background jobs, ajax actions, etc., may not always use the front controller. For this reason, we want to label any transaction as a background job and set the transaction name to the request URI or the script filename.

Don’t worry, we’ll override these later if we need to, but it’s easier to set the defaults first.

Edit app/Mage.php and add this to the top:

/**
* Log the page name in New Relic
* @custom 2011-06-04 Gabriel Koen
* @version 2011-06-04 Gabriel Koen
*/
if ( extension_loaded('newrelic') ) {
    newrelic_background_job(true);
    if ( isset($_SERVER['REQUEST_URI']) && !empty($_SERVER['REQUEST_URI']) ) {
        $_page = $_SERVER['REQUEST_URI'];
    } else {
        $_page = $_SERVER['SCRIPT_FILENAME'];
    }
    newrelic_name_transaction($_page);
}
// @custom end

Next, (re-) set the transaction name and background job status.

Edit the preDispatch() method in app/code/core/Mage/Core/Controller/Varien/Action.php as below. (The customizations are marked with @custom.)

/**
* Dispatches event before action
*/
public function preDispatch()
{
    if (!$this->getFlag('', self::FLAG_NO_CHECK_INSTALLATION)) {
        if (!Mage::isInstalled()) {
            $this->setFlag('', self::FLAG_NO_DISPATCH, true);
            $this->_redirect('install');
            return;
        }
    }
}

// Prohibit disabled store actions
if (Mage::isInstalled() && !Mage::app()->getStore()->getIsActive()) {
    Mage::app()->throwStoreException();
}

/**
* Log the page name in NewRelic
* @custom 2011-06-04 Gabriel Koen
* @version 2011-06-04 Gabriel Koen
*/
if ( extension_loaded('newrelic') ) {
    if ( isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 'xmlhttprequest' === strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) ) {
        newrelic_background_job(true);
    } else {
        newrelic_background_job(false);
    }

    $_page = $this->getRequest()->getModuleName() . '/' . $this->getRequest()->getControllerName() . '/' . $this->getRequest()->getActionName();

    if ( 'cms/index/index' === $_page ) {
        $_page = 'home';
    }

    newrelic_name_transaction($_page);
    // @custom end    if ($this->_rewrite()) {
        return;
    }

    if (!$this->getFlag('', self::FLAG_NO_START_SESSION)) {
        $checkCookie = in_array($this->getRequest()->getActionName(), $this->_cookieCheckActions);
        $checkCookie = $checkCookie && !$this->getRequest()->getParam('nocookie', false);
        $cookies = Mage::getSingleton('core/cookie')->get();
        if ($checkCookie && empty($cookies)) {
            $this->setFlag('', self::FLAG_NO_COOKIES_REDIRECT, true);
        }
        Mage::getSingleton('core/session', array('name' => $this->_sessionNamespace))->start();
    }

    Mage::app()->loadArea($this->getLayout()->getArea());

    if ($this->getFlag('', self::FLAG_NO_COOKIES_REDIRECT) && Mage::getStoreConfig('web/browser_capabilities/cookies')) {
        $this->_forward('noCookies', 'index', 'core');
        return;
    }

    if ($this->getFlag('', self::FLAG_NO_PRE_DISPATCH)) {
        return;
    }

    Mage::dispatchEvent('controller_action_predispatch', array('controller_action'=>$this));
    Mage::dispatchEvent(
    'controller_action_predispatch_'.$this->getRequest()->getRouteName(),
    array('controller_action'=>$this)
    );
    Varien_Autoload::registerScope($this->getRequest()->getRouteName());
    Mage::dispatchEvent(
    'controller_action_predispatch_'.$this->getFullActionName(),
    array('controller_action'=>$this)
    );
}

All done! You’ll see better names start showing up in New Relic within minutes.

Update — July 13, 2011: Changed example to use extension_loaded(‘newrelic’) instead of function_exists().

Advertisements

2 thoughts on “New Relic and Magento: Better Transaction Naming

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s