Code Execution Monitoring for Symfony applications using Inspector

Valerio Barbera

Hi, I’m Valerio software engineer from Italy and CTO at Inspector.

In this article I’ll show you how to measure performance and stability of your Symfony application in the production environment. Symfony is one of the most used PHP frameworks in the world, so I hope this implementation can bring real benefits in many developers’ life.

As product owner I learned on my skin how an application issue can be so hard to fix, creating negative impacts on the users experience, or block new potential customers in their on-boarding path.

Users don’t spend their time reporting bugs, they just stop using our application if it doesn’t work as expected, looking for another one that fits their needs better.

When I started to share my idea behind Inspector I realized that many developers know the problem, they spend a lot of time to investigate strange behaviors inside their application, but they didn’t know an effective solution to eliminate this complexity, avoiding customer complaints or even the loss of customers annoyed by technical problems.

Be the first to know if the application is in trouble “before” users stumble onto the problem, drastically reduce the negative impacts on their experience, giving you the right foundation to run a successful users acquisition process and to continually increase engagement with less interruptions as possible.

Symfony Code Execution Monitoring: how it works

Inspector is a Symfony bundle to add real-time code execution monitoring to your application, allowing you to work on continuous code changes while catching bugs and bottlenecks in real-time before users do.

It takes less than one minute to get started. Let me show you how it works.

Install the Symfony bundle

Run the composer command below in your terminal to get the latest version:

composer require inspector-apm/inspector-symfony

Configure the Ingestion Key

Get a fresh Ingestion key by signing up for Inspector (https://app.inspector.dev/register) and creating a new project, it takes just a few seconds.

You’ll see installation instructions directly in the app screen:

Create the inspector.yaml configuration file in your config/packages directory, and put the ingestion_key field inside:

inspector:
    ingestion_key: [your-ingestion-key]

Test everything is working

Execute our test command to check if your app send data to inspector correctly:

php bin/console inspector:test

Go to https://app.inspector.dev/home to explore your demo data.

By default Inspector traces:

  • Database interactions
  • Console commands
  • Twig view redering
  • Controllers operations
  • Unhandled Exceptions

Explore your application’s performance metrics

Now when your application receive a request Inspector automatically detect the most important events executed to fullfill the request and it create a visual representation of what happens inside your code during its normal operation.

Transaction streams in your dashboard in real time and for each transaction you can monitor what your application is doing:

Add custom segments to the timeline

Inspector monitors database queries, http requests, console commands by default, but there might be many critical statements in your code that need to be monitored in terms of performance and errors like:

  • Http calls to external services
  • Function that deals with files (pdf, excel, images)
  • Data Import/Export processes

Just as an example.

Thanks to Inspector you can add custom segments in your timeline in addition to those detected by default, to monitor the impact a custom code block has on the application performance.

Let me show you a real life example.

Suppose you have an HTTP route that executes some database oprations and also performs an http call to an external service.

Database queries are automatically detected by Inspector, but it could be interesting to see also the external http request in the timeline to monitor its execution overtime and activate alerting if somethings goes wrong.

class BlogController extends AbstractController
{
    /**
     * @Route("/posts/{slug}", methods="GET", name="blog_post")
     */
    public function postShow(Post $post): Response
    {
        $tags = this->externalService->get('tags');

        return $this->render('blog/post_show.html.twig', compact('post', 'tags'));
    }
}

You can wrap the external service call with a segment to add it in the transaction’s timeline. Type hint the Inspector service into the controller method to access the Inspector instance:

use Inspector\Inspector;

class BlogController extends AbstractController
{
    /**
     * @Route("/posts/{slug}", methods="GET", name="blog_post")
     */
    public function postShow(Post $post, Inspector $inspector): Response
    {
        $tags = $inspector->addSegment(function () {
            return this->externalService->get('tags'); // return value will be transparently returned back.
        }, 'http');

        return $this->render('blog/post_show.html.twig', compact('post', 'tags'));
    }
}

Errors & Exceptions Alerting

By default, every unhandled exception fired in your Symfony app will be reported automatically to be sure you are alerted for unpredictable errors in real time.

I wish that every change I make to my code could be perfect. But the reality is, this is not always the case. Some errors appear immediately after an update, while others pop up unpredictably. It’s a fact of life for developers. Many errors often depends by connection issues between our application and other services.

However, Inspector makes the job easier. It automates the detection of unknown issues so I no longer need to manually check the status of my apps continuously or wait reports directly from users. If something goes wrong I’ll receive a notification in real time, and after each release I can stay informed about the impact of the last code changes.

If your code fires an exception but you don’t want to block the execution, you can report the error to inspector manually for personal monitoring:

try {

    // Your dangerous external call here...

} catch (GuzzleException $exception) {
    $inspector->reportException($exception)
}

Conclusion

When a customer reports to you that something isn’t working, it forces you to drop whatever you are doing and start trying to reproduce the scenario, then recapture and reanalyze the logs in your own toolset.

Getting a true picture of what’s happening in your code can requires hours or, based on my experience, even days. Inspector can make a huge difference in terms of efficiency, productivity and customers happiness.

New to Inspector? Create your account.

Join the “Scalable Applications” community

If you want learn more about how to scale up your application, join in Scalable Applications the international community of professional developers to share strategies and experiences building scalable systems.

Join us now: https://www.facebook.com/groups/scalableapplications

Related Posts

How and why we implemented the “Repository Pattern” in our PHP backend

Hi, I’m Valerio, CTO and founder at Inspector. In this article I talk about the Repository Pattern and how we implemented it in our application to solve a scalability problem. The Repository Pattern is one of the most disccussed patterns due to a lot of conflicts with ORMs. This pattern is often intended as an

How I handled the scalability of the SQL database in Inspector

Hi, I’m Valerio software engineer, CTO and founder at Inspector. In this article I’ll talk about what I learned trying to increase the operational limits of the Inspector SQL database. Before talking about read-replicas or sharded-data, it might be helpful to introduce the problem to solve and the most common strategies to improve the ability