Raise your hands for Blackfire CLI: Profiling everything from your terminal

By Thomas di Luccio, on May 31, 2023

Triggering profiles with the browser extension is so convenient. It allows our users to profile any HTTP request with a click. It’s blazing fast! 

Yet, raise your hands if you like using CLI commands even more.

Blackfire CLI comes bundled with the Agent. As a reminder, Blackfire Agent is the daemon responsible for communicating back and forth with our servers. Blackfire probe is a language extension gathering raw performance data while a process is being handled.

Type blackfire list on your computer or a server with Blackfire installed. The command lists all the possibilities you have. This post will mostly explore the curl, run, and build-trigger commands.

Profiling HTTP requests

Let’s programmatically trigger our first profile running:
blackfire curl https://www.book.b7e.io/

As a side note, book.b7e.io is an application freely profilable by all. All you need is a Blackfire account and the browser extension. An active subscription is not required. This application is a common thread and is referred to throughout the book “PHP Code Performance Explained”, which you can read to learn all about Blackfire and Performance Optimization.

The blackfire curl command informs us of the different steps of the process. As for the browser extension, it starts with a pre-flight request that will not be profiled. The duration of this request is taken as a reference to calculate the threshold value.

Then, for GET and HEAD requests, ten samples are taken, and the different metrics are averaged to get a profile with reliable values:
https://blackfire.io/profiles/e543d728-9294-4342-890e-5f4876ae97e1/graph

Controlling your profiles with the –options

Running blackfire curl --help informs us on all the possible options. Let’s focus on some of those:

  • --samples=value allows you to override the default number of samples taken (10 for GET and HEAD, one otherwise).
  • --title=value allows you to conveniently name the profile.
  • --metadata=key=value allows you to add custom metadata to the profile providing eventually a context in which that profile has been run.
  • --debug enables the debug addon, which removes anonymization and prunning.

Let’s rerun a profile to experiment with all those options:

blackfire curl --title "This is the title" --samples 1 --metadata "foo=bar" --metadata "user_level=admin" --debug https://www.book.b7e.io/

The profile made is accessible at: https://blackfire.io/profiles/3ca76b4f-2fa1-4844-b9e7-8576f5669a5f/graph

It’s also possible to add a payload to the request being profiles. My preference for profiling POST and PUT requests are through Blackfire CLI. I usually open my browser’s web development panel, locate the request I want to optimize, then copy-as-curl.

Profiling CLI commands

CLI commands can be profiled with blackfire run. blackfire curl and blackfire run share the same signature and options.


https://blackfire.io/profiles/4ef7e1b1-ee1e-4401-ba94-ea31e6a4c9ff/graph

When a profile is triggered, the matching assertions are evaluated. This is also true when profiling a CLI command. The REGEX path entry is used for HTTP requests. The command one is for commands:

The “Getting started with the Blackfire test suite” blog series is the starting point to writing your first tests, for both your HTTP requests and your CLI commands.

tests:
    "Pages should be fast enough":
        path: "/.*" # run the assertions for all HTTP requests
        assertions:
            - "main.wall_time < 100ms" # wall clock time is less than 100ms

    "Commands should be fast enough":
        command: ".*" # run the assertions for all CLI commands
        assertions:
            - "main.wall_time < 2s" # wall clock time is less than 2s


Where are my profiles stored?

We saw that Blackfire CLI can cover any situation we want. There is nothing we can’t profile with the CLI. And this is one extra reason to never have to use a mouse.

Yet, where are those profiles stored? When profiling an HTTP request, the profile is sent in the environment configured with Environment variables.  This is something you can control where using the CLI.

Our recommendation is to explicitly define which environment the profile must be sent to using the --env=<ENV_UUID> parameter. Since v2.14.0+  the Agent uses the BLACKFIRE_SERVER_ID environment variable to determine where to send the profile. The blackfire version command tells you what version you are running. The upgrading guide will help you stay up to date with the latest versions of the Probes and the Agent.

When no target environment is specified or implicitly discovered, the profile is sent to the personal sandbox environment of the user whose personal credentials (BLACKFIRE_CLIENT_ID and BLACKFIRE_CLIENT_TOKEN) were used. Only that user can then access the profile from /my/profiles. You can use --env="My Environment" to explicitly specify your personal sandbox environment.

Controlling the Blackfire environment used to store the profiles is even more important when collaborating with others. Profiles in a personal sandbox can only be seen by their respective owners.

Such situations may happen when CLI profiling is used within a CI. If making sure new commits don’t introduce performance regressions is a strong plus, then the recommended, and comfortable way, is through Builds.

Blackfire Builds are collections of profiles triggered simultaneously, manually through Blackfire dashboard, periodically, or through the CLI. Builds rely on scenarios detailing the steps and profiles that should be triggered and evaluated. The third installment of the test suite blog post series guides you through this point. Blackfire Builds can be triggered programmatically through the build-trigger command. The documentation covers all possible ways to configure and trigger Builds, while this blog post focuses on the integration with your CI/CD pipelines.

Next week, we’ll continue our exploration of Blackfire development tools by leaning on our PHP and Python SDKs. We’ll explore how custom integrations can be designed to fit your application’s specific needs.

Meanwhile, continue the conversation on Reddit and Twitter. Let us know how you use our CLI and SDKs today, and how you would like to see possible improvements in the future.

Happy CLI Performance Optimization!

Thomas di Luccio

Thomas is a Developer Relations Engineer at Platform.sh for Blackfire.io. He likes nothing more than understanding the users' needs and helping them find practical and empowering solutions. He’ll support you as a day-to-day user.