phpsymfonysymfony4

My profiler toolbar isn't showing up in symfony 4.3.1


In my .env file, I have specified my app environment to be dev and debug to be true like so:

APP_ENV=dev
APP_DEBUG=true

In my config/packages/dev/web_profiler.yaml file I have the following:

web_profiler:
    toolbar: true
    intercept_redirects: false

framework:
    profiler: { only_exceptions: false }

The routing within config/routes/dev/web_profiler.yaml seems to be fine:

web_profiler_wdt:
    resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
    prefix: /_wdt

web_profiler_profiler:
    resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
    prefix: /_profiler

So when I run the server with symfony server:start everything is fine, but the profiler doesn't appear. Did I miss something that enables that feature within Symfony?

To clarify, the page is outputting a proper HTML page with the appropriate content. There is just no profiler showing up.


My base twig template:

<!DOCTYPE html>
<html lang="en" dir="ltr">
    <head>
        <meta charset="utf-8">
        <title>{% block title %} {% endblock %}</title>
        {{ encore_entry_script_tags('base') }}
        <link rel="icon" type="image/x-icon" href="{{ asset('build/images/favicon.ico') }}" />
        <link href="https://fonts.googleapis.com/css?family=IBM+Plex+Sans:400,500|Playfair+Display:400,700&display=swap" rel="stylesheet">
        {{ encore_entry_link_tags("base") }}
        {% block stylesheet %}{% endblock %}
    </head>
    <body {% if app.request.get('_route') == 'home' %} class='homepage' {% endif %} >
        <header>
            <div id='top-navigation' class='padding-lg__left-md padding-lg__right-md padding-lg__top-sm padding-lg__bottom-sm row row__align-center row__justify-start'>
                <span class='text-color__white text-size__small text-weight__bold margin-lg__right-lg'>Our Mission</span>
                <span class='text-color__white text-size__small text-weight__bold margin-lg__right-lg'>Our Team</span>
                <span class='text-color__white text-size__small text-weight__bold margin-lg__right-lg'>Where the Money Goes</span>
                <span class='text-color__white text-size__small text-weight__bold margin-lg__right-lg'>Community Leadership</span>
                <span class='text-color__white text-size__small text-weight__bold'>Policies</span>
                <span class='text-color__white text-size__small text-weight__bold margin-lg__left-auto icon-set'> <span class='icon size__small color__white margin-lg__right-xsm'>{{ source('@public_path'~asset('build/images/icons/feedback.svg')) }}</span>Submit Feedback</span>
            </div>
            <nav class="padding-lg__top-md padding-lg__bottom-md padding-lg__left-md padding-lg__right-md row row__align-center row__justify-start {% if app.request.get('_route') == 'home' %} homepage {% endif %}">
                <div id='logo'>
                    <a href="{{ url('home') }}">
                        <img src="{{ asset('build/images/logo_placeholder.png') }}" alt="logo">
                    </a>
                </div>
                {% if app.request.get('_route') == 'creator-register' %}

                {% else %}
                    {% if not is_granted('IS_AUTHENTICATED_FULLY') %}
                        <div class='margin-lg__left-auto'>
                            <a href="{{ url('login') }}">
                                <div class='icon-set'>
                                    <span class='icon margin-lg__right-xsm'>
                                        {{ source('@public_path'~asset('build/images/icons/user.svg')) }}
                                    </span>
                                    <span class='nav-item'>Login</span>
                                </div>
                            </a>
                        </div>
                    {% endif %}

                {% endif %}
            </nav>
        </header>
        {% if app.request.get('_route') != 'home' %} <div class='container is_top'> {% endif %}
            {% block body %} {% endblock %}
        {% if app.request.get('_route') != 'home' %} </div> {% endif %}
    </body>
</html>

Security.yaml firewall:

    firewalls:
            dev:
                pattern: ^/(_(profiler|wdt)|css|images|js)/
                security: false
            main:
                anonymous: true
                guard:
                    authenticators:
                        - App\Security\LoginFormAuthenticator
                logout:
                    path : logout
                remember_me:
                    secret: '%kernel.secret%'
                    lifetime: 2592000 #<- 30 days in seconds - defaults to one year if you take this out!

Results on php bin/console debug:router | grep _profiler:

  _profiler_home             ANY      ANY      ANY    /_profiler/                        
  _profiler_search           ANY      ANY      ANY    /_profiler/search                  
  _profiler_search_bar       ANY      ANY      ANY    /_profiler/search_bar              
  _profiler_phpinfo          ANY      ANY      ANY    /_profiler/phpinfo                 
  _profiler_search_results   ANY      ANY      ANY    /_profiler/{token}/search/results  
  _profiler_open_file        ANY      ANY      ANY    /_profiler/open                    
  _profiler                  ANY      ANY      ANY    /_profiler/{token}                 
  _profiler_router           ANY      ANY      ANY    /_profiler/{token}/router          
  _profiler_exception        ANY      ANY      ANY    /_profiler/{token}/exception       
  _profiler_exception_css    ANY      ANY      ANY    /_profiler/{token}/exception.css 

Lastly homepage controller:

<?php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class HomepageController extends AbstractController{

    /**
    * @Route("/", name="home")
    */

    public function output(){
        return $this->render('homepage/home.html.twig',[
            'title' => 'yo',
        ]);
    }
}

?>

Added public/index.php:

<?php

use App\Kernel;
use Symfony\Component\Debug\Debug;
use Symfony\Component\HttpFoundation\Request;

require dirname(__DIR__).'/config/bootstrap.php';

if ($_SERVER['APP_DEBUG']) {
    umask(0000);

    Debug::enable();
}

if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? $_ENV['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}

if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? $_ENV['TRUSTED_HOSTS'] ?? false) {
    Request::setTrustedHosts([$trustedHosts]);
}

$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

Solution

  • It's very hard, if not impossible, to debug this for you remotely. The exact problem is tied to something specific in your local setup, and someone without access to your project would not have a chance to see exactly what is wrong.

    Some general and specific troubleshooting advice for your situation:

    1st. Reinstall the profiler pack

    While unusual, the installation could be borked. Make sure your profiler package is alright.

    First remove it (composer remove profiler), and then install it again: composer require --dev profiler).

    2nd. Check the configuration

    Use Symfony's console command to verify your configuration.

    First for the built-in profiler:

    $ bin/console debug:config framework profiler
    

    Which should return something like this:

    Current configuration for "framework.profiler"
    ==============================================
    
    only_exceptions: false
    enabled: true
    collect: true
    only_master_requests: false
    dsn: 'file:%kernel.cache_dir%/profiler'
    

    And then for the profiler toolbar:

    $ bin/console debug:config web_profiler
    

    Which should return something like:

    Current configuration for extension with alias "web_profiler"
    =============================================================
    
    web_profiler:
        toolbar: true
        intercept_redirects: false
        excluded_ajax_paths: '^/((index|app(_[\w]+)?)\.php/)?_wdt'
    

    3rd. Check the container

    Check how the Profiler service will be instantiated:

    $ bin/console debug:container profiler --show-arguments
    

    Expect something like this:

    Information for Service "profiler"
    ==================================
    
     Profiler.
    
     ---------------- -------------------------------------------------------------------------------------
      Option           Value
     ---------------- -------------------------------------------------------------------------------------
      Service ID       profiler
      Class            Symfony\Component\HttpKernel\Profiler\Profiler
      Tags             monolog.logger (channel: profiler)
                       kernel.reset (method: reset)
      Calls            add, add, add, add, add, add, add, add, add, add, add, add, add, add, add, add, add
      Public           yes
      Synthetic        no
      Lazy             no
      Shared           yes
      Abstract         no
      Autowired        no
      Autoconfigured   no
      Arguments        Service(profiler.storage)
                       Service(monolog.logger.profiler)
                       1
     ---------------- -------------------------------------------------------------------------------------
    

    And then for the web_toolbar:

    # bin/console debug:container web_profiler.debug_toolbar --show-arguments
    

    For something like this:

    Information for Service "web_profiler.debug_toolbar"
    ====================================================
    
     WebDebugToolbarListener injects the Web Debug Toolbar.
    
     ---------------- ------------------------------------------------------------------------
      Option           Value
     ---------------- ------------------------------------------------------------------------
      Service ID       web_profiler.debug_toolbar
      Class            Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener
      Tags             kernel.event_subscriber
                       container.hot_path
      Public           no
      Synthetic        no
      Lazy             no
      Shared           yes
      Abstract         no
      Autowired        no
      Autoconfigured   no
      Arguments        Service(twig)
    
                       2
                       Service(router.default)
                       ^/((index|app(_[\w]+)?)\.php/)?_wdt
                       Service(web_profiler.csp.handler)
     ---------------- ------------------------------------------------------------------------
    

    (Note the 2, which enables the toolbar).

    4th. Check the event dispatcher.

    The web debug toolbar is injected during the kernel.response event. Check that the callback is appropriately hooked:

    $ bin/console debug:event-dispatcher kernel.response
    

    Which will return something like this:

    Registered Listeners for "kernel.response" Event
    ================================================
    
     ------- -------------------------------------------------------------------------------------------- ----------
      Order   Callable                                                                                     Priority
     ------- -------------------------------------------------------------------------------------------- ----------
      #1      ApiPlatform\Core\Hydra\EventListener\AddLinkHeaderListener::onKernelResponse()               0
      #2      Symfony\Component\HttpKernel\EventListener\ResponseListener::onKernelResponse()              0
      #3      Symfony\Component\HttpKernel\DataCollector\RequestDataCollector::onKernelResponse()          0
      #4      Symfony\Component\WebLink\EventListener\AddLinkHeaderListener::onKernelResponse()            0
      #5      Symfony\Component\Security\Http\RememberMe\ResponseListener::onKernelResponse()              0
      #6      ApiPlatform\Core\HttpCache\EventListener\AddHeadersListener::onKernelResponse()              -1
      #7      Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelResponse()              -100
      #8      Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener::onKernelResponse()   -128
      #9      Symfony\Component\HttpKernel\EventListener\TestSessionListener::onKernelResponse()           -128
      #10     Symfony\Component\HttpKernel\EventListener\DisallowRobotsIndexingListener::onResponse()      -255
      #11     Symfony\Component\HttpKernel\EventListener\SessionListener::onKernelResponse()               -1000
      #12     Symfony\Component\HttpKernel\EventListener\StreamedResponseListener::onKernelResponse()      -1024
     ------- -------------------------------------------------------------------------------------------- ----------
    

    Notice item #7, which is the Profiler collector (which among other things will include the X-Debug-Token header in the response, which will be later checked by the Web Debug Toolbar, which is item #8 in the above listing.

    If any of the above checks fails

    You'll have to focus on that specific part to find out why it is failing. Maybe some other bundle interfering? A problem with one of the configuration files?

    The debug bar is correctly rendered, but it performs an ajax request to HTTP instead of HTTPS

    If the rest works, the bar is actually rendered on the HTML, but now shown because you get a "mixed content" error, it's likely because you are accessing the site via a reverse proxy or load balancer, the site is not correctly configured, and Symfony has trouble figuring out the right connection scheme. Make sure you check the docs for connecting behind a proxy, and follow them thoroughly.

    Everything checks out

    ... but still not working? Well, that's weird. Make sure that your returned template has a </body> tag, and that the returned response has text/html content-type. But if all of the above checks out... it should work.


    In a comment, you say that framework.profiler.collect is set to false when performing these checks.

    Set it to true by changing config/packages/dev/web_profiler.yaml like this:

    framework:
        profiler:
            only_exceptions: false
            collect: true