Skip to content

Commit e88157b

Browse files
Write event feed import log to separate file per contest
Fixes #2169
1 parent ef70ae8 commit e88157b

File tree

4 files changed

+36
-40
lines changed

4 files changed

+36
-40
lines changed

webapp/config/packages/monolog.yaml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
monolog:
2-
# Set up logger for the event feed importer.
3-
# key, to make sure the logs don't also appear there.
4-
channels:
5-
- event-feed-importer
6-
handlers:
7-
event-feed-importer:
8-
level: info
9-
type: stream
10-
path: "%kernel.logs_dir%/event-feed-importer.log"
11-
channels: ["event-feed-importer"]
12-
131
when@dev:
142
monolog:
153
handlers:
@@ -31,10 +19,6 @@ when@dev:
3119
process_psr_3_messages: false
3220
channels: ["!event", "!doctrine", "!console"]
3321

34-
# In dev mode, also log debug messages
35-
event-feed-importer:
36-
level: debug
37-
3822
when@test:
3923
monolog:
4024
handlers:

webapp/src/DependencyInjection/Compiler/RemoveEventFeedImporterChannelFromLogs.php

Lines changed: 0 additions & 19 deletions
This file was deleted.

webapp/src/Kernel.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace App;
44

5-
use App\DependencyInjection\Compiler\RemoveEventFeedImporterChannelFromLogs;
65
use App\DependencyInjection\Compiler\SetDocLinksPass;
76
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
87
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -20,6 +19,5 @@ public function getProjectDir(): string
2019
protected function build(ContainerBuilder $container): void
2120
{
2221
$container->addCompilerPass(new SetDocLinksPass());
23-
$container->addCompilerPass(new RemoveEventFeedImporterChannelFromLogs());
2422
}
2523
}

webapp/src/Service/ExternalContestSourceService.php

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@
4444
use Exception;
4545
use InvalidArgumentException;
4646
use LogicException;
47+
use Monolog\Handler\StreamHandler;
48+
use Monolog\Level;
49+
use Monolog\Logger;
50+
use Monolog\Processor\ProcessorInterface;
4751
use Psr\Log\LoggerInterface;
4852
use Symfony\Component\DependencyInjection\Attribute\Autowire;
53+
use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
4954
use Symfony\Component\HttpClient\Exception\TransportException;
5055
use Symfony\Component\HttpFoundation\File\UploadedFile;
5156
use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException;
@@ -66,6 +71,8 @@ class ExternalContestSourceService
6671

6772
protected ?ExternalContestSource $source = null;
6873

74+
protected LoggerInterface $logger;
75+
6976
protected bool $contestLoaded = false;
7077
protected ?ContestData $cachedContestData = null;
7178
protected ?ApiInfo $cachedApiInfoData = null;
@@ -100,19 +107,28 @@ class ExternalContestSourceService
100107
'submission' => [],
101108
];
102109

110+
/**
111+
* @param \Traversable<ProcessorInterface> $logProcessors
112+
*/
103113
public function __construct(
104114
HttpClientInterface $httpClient,
105115
protected readonly DOMJudgeService $dj,
106116
protected readonly EntityManagerInterface $em,
107-
#[Autowire(service: 'monolog.logger.event-feed-importer')]
108-
protected readonly LoggerInterface $logger,
109117
protected readonly ConfigurationService $config,
110118
protected readonly EventLogService $eventLog,
111119
protected readonly SubmissionService $submissionService,
112120
protected readonly ScoreboardService $scoreboardService,
113121
protected readonly SerializerInterface&DenormalizerInterface&NormalizerInterface $serializer,
122+
#[AutowireIterator(tag: 'monolog.processor')]
123+
protected readonly \Traversable $logProcessors,
124+
#[Autowire(service: 'monolog.processor.psr_log_message')]
125+
protected readonly ProcessorInterface $psrLogMessageProcessor,
126+
#[Autowire(param: 'kernel.logs_dir')]
127+
protected readonly string $logDir,
128+
#[Autowire(param: 'kernel.environment')]
129+
protected readonly string $env,
114130
#[Autowire('%domjudge.version%')]
115-
string $domjudgeVersion
131+
string $domjudgeVersion,
116132
) {
117133
$clientOptions = [
118134
'headers' => [
@@ -269,6 +285,8 @@ public function getLastReadEventId(): ?string
269285
*/
270286
public function import(bool $fromStart, array $eventsToSkip, ?callable $progressReporter = null): bool
271287
{
288+
$this->configureLogger();
289+
272290
// We need the verdicts to validate judgement-types.
273291
$this->verdicts = $this->config->getVerdicts(['final', 'external']);
274292

@@ -2087,4 +2105,19 @@ protected function removeWarning(EventType $eventType, ?string $entityId, string
20872105
$this->em->flush();
20882106
}
20892107
}
2108+
2109+
protected function configureLogger(): void
2110+
{
2111+
// Configure a logger to use a file per contest.
2112+
// For this we need to create our own logger.
2113+
// This code is based on what Symfony does with their default loggers.
2114+
$name = sprintf('event-feed-importer-%s', $this->getContestId());
2115+
$logFile = sprintf('%s/%s.log', $this->logDir, $name);
2116+
$handler = new StreamHandler(
2117+
$logFile,
2118+
$this->env === 'dev' ? Level::Debug : Level::Info,
2119+
);
2120+
$handler->pushProcessor($this->psrLogMessageProcessor);
2121+
$this->logger = new Logger($name, [$handler], iterator_to_array($this->logProcessors));
2122+
}
20902123
}

0 commit comments

Comments
 (0)