From 2232753b994dfb65ae46f07f827b89858faea4db Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Wed, 14 Feb 2024 14:02:20 -0100 Subject: [PATCH] add hasListeners() Signed-off-by: Maxence Lange --- .../EventDispatcher/EventDispatcher.php | 26 +++++++------------ lib/private/Log.php | 21 +++++++-------- .../EventDispatcher/IEventDispatcher.php | 9 +++++++ 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/private/EventDispatcher/EventDispatcher.php b/lib/private/EventDispatcher/EventDispatcher.php index 14c13d516c0..39bf2a6afa9 100644 --- a/lib/private/EventDispatcher/EventDispatcher.php +++ b/lib/private/EventDispatcher/EventDispatcher.php @@ -33,29 +33,17 @@ use OCP\Broadcast\Events\IBroadcastEvent; use OCP\EventDispatcher\ABroadcastedEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventDispatcher; -use OCP\IContainer; use OCP\IServerContainer; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventDispatcher as SymfonyDispatcher; use function get_class; class EventDispatcher implements IEventDispatcher { - /** @var SymfonyDispatcher */ - private $dispatcher; - - /** @var IContainer */ - private $container; - - /** @var LoggerInterface */ - private $logger; - - public function __construct(SymfonyDispatcher $dispatcher, - IServerContainer $container, - LoggerInterface $logger) { - $this->dispatcher = $dispatcher; - $this->container = $container; - $this->logger = $logger; - + public function __construct( + private SymfonyDispatcher $dispatcher, + private IServerContainer $container, + private LoggerInterface $logger, + ) { // inject the event dispatcher into the logger // this is done here because there is a cyclic dependency between the event dispatcher and logger if ($this->logger instanceof Log || $this->logger instanceof Log\PsrLoggerAdapter) { @@ -86,6 +74,10 @@ class EventDispatcher implements IEventDispatcher { $this->addListener($eventName, $listener, $priority); } + public function hasListeners(string $eventName): bool { + return $this->dispatcher->hasListeners($eventName); + } + /** * @deprecated */ diff --git a/lib/private/Log.php b/lib/private/Log.php index 83ff1003294..2ad214ddec5 100644 --- a/lib/private/Log.php +++ b/lib/private/Log.php @@ -207,8 +207,10 @@ class Log implements ILogger, IDataLogger { */ public function log(int $level, string $message, array $context = []) { $minLevel = $this->getLogLevel($context); - if ($level < $minLevel && (($this->crashReporters?->hasReporters() ?? false) === false)) { - return; // we already know that log will be fully ignored + if ($level < $minLevel + && (($this->crashReporters?->hasReporters() ?? false) === false) + && (($this->eventDispatcher?->hasListeners(BeforeMessageLoggedEvent::class) ?? false) === false)) { + return; // no crash reporter, no listeners, we can stop for lower log level } array_walk($context, [$this->normalizer, 'format']); @@ -216,9 +218,7 @@ class Log implements ILogger, IDataLogger { $app = $context['app'] ?? 'no app in context'; $entry = $this->interpolateMessage($context, $message); - if ($this->eventDispatcher) { - $this->eventDispatcher->dispatchTyped(new BeforeMessageLoggedEvent($app, $level, $entry)); - } + $this->eventDispatcher?->dispatchTyped(new BeforeMessageLoggedEvent($app, $level, $entry)); $hasBacktrace = isset($entry['exception']); $logBacktrace = $this->config->getValue('log.backtrace', false); @@ -326,8 +326,10 @@ class Log implements ILogger, IDataLogger { $level = $context['level'] ?? ILogger::ERROR; $minLevel = $this->getLogLevel($context); - if ($level < $minLevel && (($this->crashReporters?->hasReporters() ?? false) === false)) { - return; // we already know that log will be fully ignored + if ($level < $minLevel + && (($this->crashReporters?->hasReporters() ?? false) === false) + && (($this->eventDispatcher?->hasListeners(BeforeMessageLoggedEvent::class) ?? false) === false)) { + return; // no crash reporter, no listeners, we can stop for lower log level } // if an error is raised before the autoloader is properly setup, we can't serialize exceptions @@ -343,12 +345,9 @@ class Log implements ILogger, IDataLogger { $data = array_merge($serializer->serializeException($exception), $data); $data = $this->interpolateMessage($data, isset($context['message']) && $context['message'] !== '' ? $context['message'] : ('Exception thrown: ' . get_class($exception)), 'CustomMessage'); - array_walk($context, [$this->normalizer, 'format']); - if ($this->eventDispatcher) { - $this->eventDispatcher->dispatchTyped(new BeforeMessageLoggedEvent($app, $level, $data)); - } + $this->eventDispatcher?->dispatchTyped(new BeforeMessageLoggedEvent($app, $level, $data)); try { if ($level >= $minLevel) { diff --git a/lib/public/EventDispatcher/IEventDispatcher.php b/lib/public/EventDispatcher/IEventDispatcher.php index 0a96fa799d4..a84e0fe2f3b 100644 --- a/lib/public/EventDispatcher/IEventDispatcher.php +++ b/lib/public/EventDispatcher/IEventDispatcher.php @@ -69,6 +69,15 @@ interface IEventDispatcher { */ public function addServiceListener(string $eventName, string $className, int $priority = 0): void; + /** + * @template T of \OCP\EventDispatcher\Event + * @param string $eventName preferably the fully-qualified class name of the Event sub class + * + * @return bool TRUE if event has registered listeners + * @since 29.0.0 + */ + public function hasListeners(string $eventName): bool; + /** * @template T of \OCP\EventDispatcher\Event * @param string $eventName