New Relic Real user monitoring hooks for Drupal

If you are using New Relic for performance monitoring a Drupal project, you may have noticed a large discrepency between the browser throughput and app server throughput. In the example that follows, the difference is 100:1. The cause is a limitation in the auto-instrument feature:

If you also select Cache pages for anonymous users, RUM JavaScript (rum.js) is not inserted into the served pages for anonymous users. This is because Drupal's pages are compressed directly from the database before they are stored in the cache (with gzip), so New Relic's PHP agent does not have a chance to parse any HTML. In this situation, manual instrumentation provides a better opportunity to capture data for anonymous users.

The docs go on to provide advice for manual instrumentation, however the New Relic solution is suboptimal for three reasons:

  1. By using page.tpl, the timing header ends up in the <body> element, well after the head, script, and style tags. I believe the result is inaccurate timing, since the clock won't start until those resources are already downloaded and executed.
  2. It does not account for multiple themes – a Drupal site typically has at least two themes (one for presentation and one for administration), sometimes many more. A single theme can also have multiple page templates.
  3. The suggestion to edit themes/garland/page.tpl.php violates the Don't hack core mantra.

After several experiments, I ended up with this module code, which has been working well for us:

/**
 * Implements hook_init().
 */
function mymodule_init() {
  /* This block adds the New Relic timing header & footer.
   * drupal_add_html_head() works better than drupal_add_js
   * because it can be weighted earlier in the DOM.
   *
   * @see http://www.metaltoad.com/blog/new-relic-real-user-monitoring-hooks-drupal
   */
  if (extension_loaded('newrelic')) {
    drupal_add_html_head(array(
      '#type' => 'html_tag',
      '#tag' => 'script',
      '#value' => newrelic_get_browser_timing_header(FALSE),
      '#weight' => -999, // Right after charset attribute
    ), 'newrelic');
    drupal_add_js(newrelic_get_browser_timing_footer(FALSE),
      array('type' => 'inline', 'scope' => 'footer', 'weight' => 1000));
  }
}

Comments

Great code, works4me!
Are you planning to contrib the code? If not, do you mind if I do?

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <cpp>, <java>, <php>. The supported tag styles are: <foo>, [foo].
  • Web page addresses and email addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Ready for transformation?