egulias/tag-debug-command-bundle
Installation:
composer require egulias/tag-debug-command-bundle
Add to AppKernel.php (Symfony 2.x) or config/bundles.php (Symfony 3+):
new Egulias\TagDebugCommandBundle\TagDebugCommandBundle(),
First Run: Navigate to your project root and execute:
php app/console container:tag-debug
This lists all tagged services in your container with their tags, IDs, and class names.
Quick Debugging:
Use --filter to narrow results (e.g., debug only monolog.logger tags):
php app/console container:tag-debug --filter name=monolog.logger
Dependency Inspection:
Use --filter to inspect tagged services for specific bundles (e.g., filter name=doctrine.event_listener).
Example:
php app/console container:tag-debug --filter name=doctrine.event_listener
Private Service Debugging:
Enable private service visibility with --show-private to debug internal services (e.g., Symfony’s router):
php app/console container:tag-debug --show-private
Attribute Filtering:
Filter by tag attributes (e.g., debug monolog.logger services with a specific channel attribute):
php app/console container:tag-debug --filter attribute_name=channel --filter name=monolog.logger
CI/CD Pipelines:
Add the command to your test suite to validate tagged services (e.g., monolog.logger or twig.extension).
Example in phpunit.xml:
<php>
<env name="DEBUG_TAGS" value="true"/>
</php>
<listeners>
<listener class="App\Tests\DebugTagsListener" />
</listeners>
Then run:
php app/console container:tag-debug --filter name=monolog.logger || exit 1
Custom Filters: Extend the bundle by creating a custom filter class (see README) to debug complex tag structures (e.g., nested arrays or custom metadata).
Autoloaded Commands:
In Symfony Flex projects, the command is auto-registered. For custom bundles, ensure the command is loaded via services.yaml:
services:
Egulias\TagDebugCommandBundle\Command\TagDebugCommand:
tags: ['console.command']
Performance:
The command scans the entire container, which can be slow for large applications. Use --filter aggressively to limit scope.
Tip: Cache results in development by storing output in a file (e.g., debug_tags.log) and diffing changes.
Private Services:
--show-private exposes internal Symfony services (e.g., router, security.token_storage). Overuse can clutter output.
Tip: Restrict to specific tags (e.g., --filter name=security.voter).
Tag Attribute Quirks:
Attributes with special characters (e.g., priority=1) may require escaping in filters:
php app/console container:tag-debug --filter attribute_name=priority --filter name=monolog.logger --filter value=1
Symfony 3+ Compatibility:
The bundle is Symfony 2.x-focused. For Symfony 4/5, ensure autowiring is disabled for the command or manually register it in config/services.yaml:
services:
Egulias\TagDebugCommandBundle\Command\TagDebugCommand:
arguments:
$container: '@service_container'
Missing Tags: If a tagged service isn’t listed, verify:
services.yaml/config/services.xml:
services:
App\Service\MyService:
tags: ['my.tag']
AppKernel.php/bundles.php order).Custom Filter Issues:
For custom filters, ensure they implement Egulias\TagDebugCommandBundle\Filter\FilterInterface and are registered in the bundle’s Resources/config/services.xml:
<service id="app.custom_filter" class="App\Filter\CustomFilter">
<tag name="tag_debug.filter" />
</service>
Output Formatting:
Pipe output to grep for quick searches:
php app/console container:tag-debug | grep "monolog"
Custom Filters: Create a filter class to match complex tag structures (e.g., arrays or objects):
namespace App\Filter;
use Egulias\TagDebugCommandBundle\Filter\FilterInterface;
class ArrayValueFilter implements FilterInterface
{
public function matches(array $tags, string $filterName, array $filterParams): bool
{
return isset($tags[$filterParams[0]]['value']['array_key']);
}
}
Register it in services.xml:
<service id="app.array_value_filter" class="App\Filter\ArrayValueFilter">
<tag name="tag_debug.filter" alias="array_value" />
</service>
Post-Processing: Override the command class to add custom logic (e.g., export to JSON):
namespace App\Command;
use Egulias\TagDebugCommandBundle\Command\TagDebugCommand;
class CustomTagDebugCommand extends TagDebugCommand
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$tags = $this->getTags($input);
$output->writeln(json_encode($tags));
}
}
Update services.yaml to replace the default command:
services:
App\Command\CustomTagDebugCommand:
tags: ['console.command']
How can I help you explore Laravel packages today?