diff --git a/composer.json b/composer.json
index d5efd789..8233eac3 100644
--- a/composer.json
+++ b/composer.json
@@ -49,7 +49,8 @@
"symfony/security-bundle": "^6.4|^7.0",
"symfony/translation": "^6.4|^7.0",
"symfony/twig-bundle": "^6.4|^7.0",
- "symplify/easy-coding-standard": "^11.3"
+ "symplify/easy-coding-standard": "^11.3",
+ "symfony/monolog-bundle": "^3.10"
},
"replace": {
"yokai/batch": "self.version",
diff --git a/src/batch-symfony-framework/docs/getting-started.md b/src/batch-symfony-framework/docs/getting-started.md
index 593fc723..026e58df 100644
--- a/src/batch-symfony-framework/docs/getting-started.md
+++ b/src/batch-symfony-framework/docs/getting-started.md
@@ -104,6 +104,19 @@ The job launcher that will be injected depends on the packages you have installe
- if `yokai/batch-symfony-console` is installed, you will receive a `Yokai\Batch\Bridge\Symfony\Console\RunCommandJobLauncher`
- otherwise you will receive a `Yokai\Batch\Launcher\SimpleJobLauncher`
+
+## Define a custom BatchLogger
+In a symfony project, a monolog handler could be declared as of:
+```yaml
+# config/packages/monolog.yaml
+monolog:
+ handlers:
+ batch:
+ type: service
+ id: service.to.be.defined
+```
+
+
## On the same subject
- [What is a job execution storage ?](https://github.com/yokai-php/batch/blob/0.x/docs/domain/job-execution-storage.md)
diff --git a/src/batch-symfony-framework/src/DependencyInjection/YokaiBatchExtension.php b/src/batch-symfony-framework/src/DependencyInjection/YokaiBatchExtension.php
index 7f269e1b..f42a0268 100644
--- a/src/batch-symfony-framework/src/DependencyInjection/YokaiBatchExtension.php
+++ b/src/batch-symfony-framework/src/DependencyInjection/YokaiBatchExtension.php
@@ -5,6 +5,7 @@
namespace Yokai\Batch\Bridge\Symfony\Framework\DependencyInjection;
use Composer\InstalledVersions;
+use Psr\Log\LoggerInterface;
use Sonata\AdminBundle\Templating\TemplateRegistryInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader as ConfigLoader;
@@ -22,6 +23,7 @@
use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Templating\SonataAdminTemplating;
use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Templating\TemplatingInterface;
use Yokai\Batch\Launcher\JobLauncherInterface;
+use Yokai\Batch\Logger\BatchLogger;
use Yokai\Batch\Storage\FilesystemJobExecutionStorage;
use Yokai\Batch\Storage\JobExecutionStorageInterface;
use Yokai\Batch\Storage\ListableJobExecutionStorageInterface;
@@ -71,6 +73,8 @@ public function load(array $configs, ContainerBuilder $container): void
JobLauncherInterface::class,
\array_keys(\array_filter($launchers))[0] ?? 'yokai_batch.job_launcher.simple'
);
+ $container->registerAliasForArgument('yokai_batch.logger', LoggerInterface::class, 'yokaiBatchLogger');
+ dump($container->getAliases());
}
private function installed(string $package): bool
diff --git a/src/batch-symfony-framework/src/Resources/services/global/logger.xml b/src/batch-symfony-framework/src/Resources/services/global/logger.xml
new file mode 100644
index 00000000..c15d5235
--- /dev/null
+++ b/src/batch-symfony-framework/src/Resources/services/global/logger.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/batch/src/Logger/BatchLogger.php b/src/batch/src/Logger/BatchLogger.php
new file mode 100644
index 00000000..474f0559
--- /dev/null
+++ b/src/batch/src/Logger/BatchLogger.php
@@ -0,0 +1,48 @@
+batchLogger = $event->getExecution()->getLogger();
+ }
+
+ /**
+ * Forget the logger
+ */
+ public function onPostExecute(PostExecuteEvent $event): void
+ {
+ $this->batchLogger = null;
+ }
+
+ /**
+ * Log with the batchLogger defined in the PreExecuteEvent or with nullLogger if nothing remembered
+ *
+ * @param array $context
+ * @throws InvalidArgumentException
+ */
+ public function log($level, Stringable|string $message, array $context = []): void
+ {
+ ($this->batchLogger ?? new NullLogger())->log($level, $message, $context);
+ }
+}
diff --git a/src/batch/tests/Logger/BatchLoggerTest.php b/src/batch/tests/Logger/BatchLoggerTest.php
new file mode 100644
index 00000000..14743972
--- /dev/null
+++ b/src/batch/tests/Logger/BatchLoggerTest.php
@@ -0,0 +1,40 @@
+addListener(PreExecuteEvent::class, [$logger, 'onPreExecute']);
+ $dispatcher->addListener(PostExecuteEvent::class, [$logger, 'onPostExecute']);
+
+ $execution = JobExecution::createRoot('123', 'test.job_executor');
+
+ $logger->log('info', 'before');
+ $preExecuteEvent = new PreExecuteEvent($execution);
+ $dispatcher->dispatch($preExecuteEvent);
+
+ $logger->log('info', 'between');
+
+ $postExecuteEvent = new PostExecuteEvent($execution);
+ $dispatcher->dispatch($postExecuteEvent);
+ $logger->log('info', 'after');
+
+ self::assertStringNotContainsString('before', $execution->getLogs()->__toString());
+ self::assertStringContainsString('between', $execution->getLogs()->__toString());
+ self::assertStringNotContainsString('after', $execution->getLogs()->__toString());
+ }
+}
diff --git a/tests/symfony/src/Job/Country/CountryJob.php b/tests/symfony/src/Job/Country/CountryJob.php
index 71870b65..2f349b85 100644
--- a/tests/symfony/src/Job/Country/CountryJob.php
+++ b/tests/symfony/src/Job/Country/CountryJob.php
@@ -4,6 +4,7 @@
namespace Yokai\Batch\Sources\Tests\Symfony\App\Job\Country;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Yokai\Batch\Bridge\OpenSpout\Writer\FlatFileWriter;
use Yokai\Batch\Bridge\Symfony\Framework\JobWithStaticNameInterface;
@@ -56,14 +57,18 @@ final class CountryJob extends AbstractDecoratedJob implements
private ItemWriterInterface $writer;
private array $countries = [];
private bool $flushed = false;
+ private LoggerInterface $yokaiBatchLogger;
public static function getJobName(): string
{
return 'country';
}
- public function __construct(JobExecutionStorageInterface $executionStorage, KernelInterface $kernel)
- {
+ public function __construct(
+ JobExecutionStorageInterface $executionStorage,
+ KernelInterface $kernel,
+ LoggerInterface $yokaiBatchLogger
+ ) {
$writePath = fn(string $format) => new StaticValueParameterAccessor(
ARTIFACT_DIR . '/symfony/country/countries.' . $format
);
@@ -81,6 +86,7 @@ public function __construct(JobExecutionStorageInterface $executionStorage, Kern
new FlatFileWriter($writePath('csv'), null, null, $headers),
new JsonLinesWriter($writePath('jsonl')),
]);
+ $this->yokaiBatchLogger = $yokaiBatchLogger;
parent::__construct(
new ItemJob(
@@ -95,6 +101,8 @@ public function __construct(JobExecutionStorageInterface $executionStorage, Kern
public function process(mixed $item): array
{
+ $this->yokaiBatchLogger->log('info', 'log process');
+
return ['iso2' => $item['code'], $item['_key'] => $item['value']];
}
diff --git a/tests/symfony/tests/CountryJobSet.php b/tests/symfony/tests/CountryJobSet.php
index 52eb49c7..3bfee185 100644
--- a/tests/symfony/tests/CountryJobSet.php
+++ b/tests/symfony/tests/CountryJobSet.php
@@ -74,6 +74,7 @@ static function (JobExecution $execution) {
'{"iso2":"GB","iso3":"GBR","name":"United Kingdom","continent":"EU","currency":"GBP","phone":"44"}',
$jsonl
);
+ Assert::assertStringContainsString('log process', $execution->getLogs()->__toString());
},
];
}