Steven Musumeche
Steven Musumeche

Reputation: 2936

Symfony Profiler on Console Command

When running a Symfony app in the dev environment, the web debug toolbar allows me to see how many queries that Doctrine generated. Is there a similar profiler option for Console commands?

Upvotes: 15

Views: 14035

Answers (5)

allan.simon
allan.simon

Reputation: 4306

Since Symfony 6.4+ it's now built-in

Simply run the command with --profile and it will appear in the profiler (you can get the clickable link by using -v )

see https://symfony.com/blog/new-in-symfony-6-4-command-profiler

example

console -v --profile app:my-command

Upvotes: 3

Artem
Artem

Reputation: 1646

It's possible to run a command from the controller or other services. So all command information will be in the profiler.

There is an example from symfony docs

// src/Controller/DebugTwigController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;

class DebugTwigController extends AbstractController
{
    public function debugTwig(KernelInterface $kernel): Response
    {
        $application = new Application($kernel);
        $application->setAutoExit(false);

        $input = new ArrayInput([
            'command' => 'debug:twig',
            // (optional) define the value of command arguments
            'fooArgument' => 'barValue',
            // (optional) pass options to the command
            '--bar' => 'fooValue',
        ]);

        // You can use NullOutput() if you don't need the output
        $output = new BufferedOutput();
        $application->run($input, $output);

        // return the output, don't use if you used NullOutput()
        $content = $output->fetch();

        // return new Response(""), if you used NullOutput()
        return new Response($content);
    }
}

Upvotes: 0

Andrew Zhilin
Andrew Zhilin

Reputation: 1708

First of all, symfony profiler depends on Request. Thats why its cant be used in console commands out of the box and, probably, it will not be fixed. Related symfony issue

But you still can access default DBAL profiling logger. It should be instance of Doctrine\DBAL\Logging\DebugStack It have public queries property, which hold all executed queries, parameters, execution time etc. Whenever you will need to debug actual queries - you can do in such a way

    /** @var $em Registry */
    $em = $this->getContainer()->get('doctrine')->getManager();
    $profiler = $this->getContainer()->get('doctrine.dbal.logger.profiling.default');

    $shop = $em->getRepository(Shop::class)->find(7);
    $sku = $em->getRepository(Sku::class)->find(45);

    // clear profiles data, we want to profile Criteria below
    $profiler->queries = [];
    $shopWares = $shop->getShopWarePagesForSku($sku);

    $output->writeln(var_export($profiler->queries));

It would generate output like

array (
      3 => 
      array (
        'sql' => 'SELECT ...... FROM ShopWarePage t0 WHERE (t0.sku_id = ? AND t0.sku_id = ?)',
        'params' => 
        array (
          0 => 45,
          1 => 7,
        ),
        'types' => 
        array (
          0 => 'integer',
          1 => 'integer',
        ),
        'executionMS' => 0.00075292587280273438,
      ),
    )

Upvotes: 2

Chris
Chris

Reputation: 754

Yeah, --verbose is useful as @manolo mentioned. You can control what gets output in -v -vv -vvv from the monolog handler config

monolog:
handlers:
    main:
        type:   stream
        path:   "%kernel.logs_dir%/%kernel.environment%.log"
        level:  debug
    console:
        type:   console
        bubble: false
        verbosity_levels:
            VERBOSITY_VERBOSE: INFO
            VERBOSITY_VERY_VERBOSE: DEBUG
        channels: ["!doctrine"]
    console_very_verbose:
        type:   console
        bubble: false
        verbosity_levels:
            VERBOSITY_VERBOSE: NOTICE
            VERBOSITY_VERY_VERBOSE: NOTICE
            VERBOSITY_DEBUG: DEBUG
        channels: ["doctrine"]

Notice how you can even disable a channel -v or --verbose will only output non doctrine logs at the specified verbose levels.

Upvotes: 5

Robin Maree
Robin Maree

Reputation: 51

As described in the docs, the profiler only collects information for all requests. I believe there is no collector for the console commands. One of the ways to get more insight into the queries executed by Doctrine is to check your log files. For example, you can do something like this on Unix based systems:

tail -f app/logs/dev.log | grep doctrine

Also see: http://symfony.com/doc/current/book/internals.html#profiler

Upvotes: 5

Related Questions