Reputation: 860
I have a factory class that creates different objects and I have a lot of loggers defined for each type of object. And I want to get all loggers collection in my factory. Before I just used a ContainerInterface in my factory constructor, but since Symfony 5.1 container autowiring is deprecated. Now I can not find a way to get a collection of loggers. I tried to use
!tagged_iterator { tag: 'monolog.logger' }
and also tried to set a tag for LoggerInterface and get a tagged_iterator for it, but it didn't work. I suggest that it is because loggers are not real classes.
Upvotes: 1
Views: 903
Reputation: 48865
This might be overkill but as you say the logger services are a bit unusual. Seems like they should be tagged or be taggable by LoggerInterface but I ran some test and could not get it to work. Here is a brute force approach which relies on logger services having ids of monolog.logger.name:
# Start with a service locator class
namespace App\Service;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ServiceLocator;
class LoggerLocator extends ServiceLocator
{
// Just to specify the return type to keep IDEs happy
public function get($id) : LoggerInterface
{
return parent::get($id);
}
}
...
# now make the kernel into a compiler pass
# src/Kernel.php
class Kernel extends BaseKernel implements CompilerPassInterface
...
public function process(ContainerBuilder $container)
{
$loggerServices = [];
foreach($container->getServiceIds() as $id) {
if (!strncmp($id,'monolog.logger.',15)) {
//echo 'Logger ' . $id . "\n";
$loggerServices[$id] = new Reference($id);
}
}
$loggerLocator = $container->getDefinition(LoggerLocator::class);
$loggerLocator->setArguments([$loggerServices]);
}
# and now we can inject the locator where it is needed
class SomeController {
public function index(Request $request, LoggerLocator $loggerLocator)
{
dump($loggerLocator);
$logger = $loggerLocator->get('monolog.logger.' . $name);
Seems like there should be a way to do this just through configuring but a pass is easy enough I guess.
Upvotes: 1