As discussed in one of my last blog posts, we really like New Relic for performance metrics and use it a lot. Unfortunately there isn’t an extension for HHVM (yet) and HHVM is becoming an important part in our setup. But – a big great coincidence – New Relic released an Agent SDK and with that, an example extension for HHVM and WordPress. That was a great start for me to get behind the whole thing.
I had mainly two goals for this. Have an API compatible extension to the official New Relic PHP extension, so that we can use the same code for the Zend PHP Engine and HHVM. In our Symfony2 projects, we use the Ekino New Relic Bundle and we didn’t want to have to change that. And as a bonus, make profiling as informative as possible so that we can see which part of the call takes how long.
Writing hhvm extension is surprisingly easy (at least if you have a template ;)), you can even write the easy stuff in PHP (or Hack) and only for the more advanced stuff switch to C++, see ext_newrelic.php as an example of that.
New Relic is continuously adding new features to their Agent SDK and today, we’re almost API complete (the only important thing missing is being able to change the license key or the appname from within HHVM).
If you want to use New Relic on your HHVM server, just compile and install the extension from github.com/chregu/hhvm-newrelic-ext/ and you’re good to go. You can send attributes, errors and it will also send the time your requests needed.
Of course, one of the main features of New Relic is to see, where your requests spend their time. That needed a little bit more work. And I came up with two solutions.
Solution 1 needs a patched and recompiled HHVM and hooks into the HOTPROFILING of HHVM. This is disabled by default, so you have to enable this with
cmake -D HOTPROFILER:BOOL=ON . before compiling HHVM (you also have to do that, if you want to use xhprof). And of course my patched HHVM, which adds the possibility to send profiling data to New Relic. You can then enable it with
newrelic_profiling_enable($level) in your code, where level is the amount of levels (depth) you want to collect. If you set that too high, you won’t see everything.
If you enable profiling with
newrelic_profiling_enable(), it will make your requests approx. 20-50% slower (but still much faster than with Zend PHP), so it’s advised not to use that all the time. If you don’t use that call, I couldn’t see any performance difference to an HHVM without HOTPROFILER compiled in (I’m sure there is, but it must be really low).
Solution 2 doesn’t need a patched HHVM (just the HHVM New Relic extension), but will make it much slower (2-3 times as slow, depending on how many function calls you have). It uses the HHVM function
fb_setprofile, which will get called on every function request and collects data this way. It’s also enabled with
newrelic_profiling_enable($level), the extension automatically chooses the better option.
With this new relic extension and the patched HHVM, we can now collect almost the same data into New Relic as with the official PHP extension, which helps a lot in finding performance problems and bottlenecks. It’s not perfect yet, but we will get there (unless New Relic publishes an official HHVM extension before that, which would be great of course as well).
I also want to thank New Relic for their quick support and fixing when I had questions or found something dubious. Really appreciated (but of course it would sometimes have been easier, if the source code to the Agent SDK was available ;))
Feel free to use and extend the extension and patches of course are always welcome.
Thanks for this article, Christian! I’m a big fan of NewRelic and I hope it’s fine for you if I link your article post on the german speaking Hack & HHVM support forum http://www.fbhack.de
Nice article and awesome that you made the HHVM extension!
We’re nearing launch of our start-up and we need to start setting up monitoring etc. and I’d love to use New Relic but it will have to work with HHVM properly.
Are you guys using the extension in production?
Is the performance loss without enabling the traces really neglectable?
are you only running the the profiling on a random small subset of request or some similar?
We’re using it in production and don’t see any performance loss without the traces enbaled (but I don’t have any proof for that ;))
And our production servers are only 2 servers right now (varnish helps a lot for just needing 2), so there’s no small subset ;) We enable the profiling if we need better insight on one of the servers.
I noticed that some changes to HHVM for New Relic support were merged in several months ago. Am I right in assuming that, if you compile with HOTPROFILER, you can now use mainline HHVM rather than your fork?
Ian, I can confirm that you can use the mainline hhvm fork. I used the Ubuntu repository to install hhvm and hhvm-dev, then downloaded the 0.12.12 archive version of the newrelic agent sdk here: http://download.newrelic.com/agent_sdk/archive/ and compiled the newrelic.so hhvm extension using that. It’s missing functionality like database metrics and sql traces, but it works.