Skip to content

Commit

Permalink
feature #90 add global logger service that logs in job
Browse files Browse the repository at this point in the history
  • Loading branch information
guich25 committed Jan 10, 2024
1 parent f6f6826 commit afa580d
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 2 deletions.
14 changes: 14 additions & 0 deletions src/batch-symfony-framework/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ 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
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<defaults public="false"/>

<service id="yokai_batch.logger" class="Yokai\Batch\Logger\BatchLogger">
<tag name="kernel.event_listener" method="onPreExecute" event="Yokai\Batch\Event\PreExecuteEvent"/>
<tag name="kernel.event_listener" method="onPostExecute" event="Yokai\Batch\Event\PostExecuteEvent"/>
</service>

</services>
</container>
54 changes: 54 additions & 0 deletions src/batch/src/Logger/BatchLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Tucania project.
*
* Copyright (C) Tucania (https://www.tucania.com/) - All Rights Reserved
*
* For the full copyright and license information, please view the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);

namespace Yokai\Batch\Logger;

use Psr\Log\AbstractLogger;
use Psr\Log\InvalidArgumentException;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Stringable;
use Yokai\Batch\Event\PostExecuteEvent;
use Yokai\Batch\Event\PreExecuteEvent;

/**
* BatchLogger allow to log with the jobExecutionLogger
*/
class BatchLogger extends AbstractLogger
{
private ?LoggerInterface $batchLogger = null;

/**
* Access and remember the logger
*/
public function onPreExecute(PreExecuteEvent $event): void
{
$this->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<string, mixed> $context
* @throws InvalidArgumentException
*/
public function log($level, Stringable|string $message, array $context = []): void
{
($this->batchLogger ?? new NullLogger())->log($level, $message, $context);
}
}
40 changes: 40 additions & 0 deletions src/batch/tests/Logger/BatchLoggerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Yokai\Batch\Tests\Logger;

use PHPUnit\Framework\TestCase;
use Yokai\Batch\Event\PostExecuteEvent;
use Yokai\Batch\Event\PreExecuteEvent;
use Yokai\Batch\JobExecution;
use Yokai\Batch\Logger\BatchLogger;
use Yokai\Batch\Tests\Dummy\DebugEventDispatcher;

class BatchLoggerTest extends TestCase
{
public function testLaunch(): void
{
$dispatcher = new DebugEventDispatcher();
$logger = new BatchLogger();

$dispatcher->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());
}
}
12 changes: 10 additions & 2 deletions tests/symfony/src/Job/Country/CountryJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -56,14 +57,18 @@ final class CountryJob extends AbstractDecoratedJob implements
private ItemWriterInterface $writer;
private array $countries = [];
private bool $flushed = false;
private LoggerInterface $batchLogger;

public static function getJobName(): string
{
return 'country';
}

public function __construct(JobExecutionStorageInterface $executionStorage, KernelInterface $kernel)
{
public function __construct(
JobExecutionStorageInterface $executionStorage,
KernelInterface $kernel,
LoggerInterface $batchLogger
) {
$writePath = fn(string $format) => new StaticValueParameterAccessor(
ARTIFACT_DIR . '/symfony/country/countries.' . $format
);
Expand Down Expand Up @@ -91,10 +96,13 @@ public function __construct(JobExecutionStorageInterface $executionStorage, Kern
$executionStorage
),
);
$this->batchLogger = $batchLogger;
}

public function process(mixed $item): array
{
$this->batchLogger->log('info', 'log process');

return ['iso2' => $item['code'], $item['_key'] => $item['value']];
}

Expand Down
13 changes: 13 additions & 0 deletions tests/symfony/src/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Bundle\MonologBundle\MonologBundle;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
Expand All @@ -31,6 +32,7 @@ public function registerBundles(): iterable
yield new TwigBundle();
yield new SecurityBundle();
yield new YokaiBatchBundle();
yield new MonologBundle();
}

public function getProjectDir(): string
Expand Down Expand Up @@ -108,6 +110,17 @@ protected function configureContainer(ContainerConfigurator $container): void
],
]);

$container->extension('monolog', [
'handlers' => [
'batch' => [
'type' => 'service',
'service' => [
'id' => 'Yokai\Batch\Logger\BatchLogger',
],
],
],
]);

$container->services()
->set('logger', Logger::class)
->args([null, '%kernel.logs_dir%/test.log', null, new Reference(RequestStack::class)])
Expand Down
1 change: 1 addition & 0 deletions tests/symfony/tests/CountryJobSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
},
];
}
Expand Down

0 comments on commit afa580d

Please sign in to comment.