Feature Focus: “Metrics Reloaded”, Episode 2
Going further with metrics, thanks to the Metrics Explorer. It is now easier to write Blackfire tests.
Blog post series index:
In the previous episode, we discovered Blackfire metrics and how they can be useful, especially when we start to define assertions and tests. We saw that we could define regression and/or behaviour tests, based on metrics collected from your application profile.
Find your way in the Metrics Jungle
We saw that, with Blackfire, assertions are based on metrics. Blackfire provides hundreds of built-in metrics (587 and counting), based on libraries, frameworks, CMSes, or even your app engine settings (e.g. PHP settings). However, it can be tedious to start writing tests with such a long list, even though it can help.
What if it was possible to spot metrics when analyzing a profile? This is where the Metrics Explorer comes into place…
The Metrics Explorer
Profile, Test, Fix, Repeat.
The Blackfire motto remains valid when analysing your application behaviour. When you are doing on-demand profiles, i.e. to figure out a performance issue on specific parts of your application, a good approach is to write non-regression tests as soon as you managed to find bottlenecks. In this regard, the Metrics Explorer eases the process by spotting the right metrics for you.
Viewing metrics in the callgraph’s functions list
Considering this profile, we can see that
Doctrine\ORM\UnitOfWork::createEntity is called way too much and constitutes 13.5% of the overall wall-time.
Now, let’s have a look at the detailed function call panel:
We can see that this function call contributes to the
doctrine.entities.created metric, which is a built-in one. We can also notice the purple square on the top left of the panel. All functions contributing to a metric (including custom metrics, but we will cover this later) are being assigned a colored square, making them easy to spot in the functions list.
Metrics and submetrics
But did you know that a metric can be part of a wider one? Let’s have a look at another function:
Here we can see that
PDOStatement::execute() contributes to
sql.pdo.queries, which bubbles up to
sql.queries and then to
sql metrics. This gives you the opportunity to write your assertions against abstract metrics, e.g. against
sql.queries instead of
sql.pdo.queries which might be too specific.
Writing the Test
In our previous example, we determined that we were creating too many Doctrine Entities. Let’s now create a test which will help us ensure this doesn’t happen anymore:
tests: "Not too many Doctrine entities": path: "/.*" assertions: - "metrics.doctrine.entities.created.count <= 50"
Note that the metric is prefixed by the
metricskeyword, and suffixed by the dimension. There are many available dimensions, as described in the metrics documentation.
This is a very robust test, as it relies on a metric which will not fluctuate, as opposed to time values, and we should always avoid testing against time values.
Here we take a reasonable margin for all pages of our website. This test will fail if more than 50 Doctrine entities are created.
But what if there is no metrics for what I want to test?
This is where custom metrics come into place, but let’s not spoil the next episode 😉.
A Few Tips
I could not finish this article without giving you a few tips, which I’m sure will be very useful to you!
Function List Filtering
In the Call-Graph view, you can filter out the function list by function name. Did you know you could also filter by metric name?
Even better, for metrics defining argument capturing, it is also possible to filter by argument! This is very convenient when you want to know where this or that SQL query comes from 😉.
The Timeline View
The Timeline View is already all about metrics, as explained in the previous article. Sometimes, in order to switch from the profile to our code, we need to get the name of the class and/or method.
Click on a metric block to make the Callstack appear ✨.
To Be Concluded…
We just started to unveil the great power of metrics 💪… In the next episode, we will see how to define custom metrics, based on your own business code.