Skip to content

fix(logger): accept any Monolog handler as process manager log writer - #238

Open
jremmurd wants to merge 1 commit into
valantic-at:pimcore11from
jremmurd:fix/logger-handler-interface-p11
Open

fix(logger): accept any Monolog handler as process manager log writer#238
jremmurd wants to merge 1 commit into
valantic-at:pimcore11from
jremmurd:fix/logger-handler-interface-p11

Conversation

@jremmurd

Copy link
Copy Markdown
Contributor

Problem

AbstractLogger::createStreamHandler() is typed StreamHandler | ApplicationLoggerDb | null, but its only consumer is MonitoringItem::getLogger():

$streamHandler = $obj->createStreamHandler($loggerConfig, $this);
if ($streamHandler) {
    $this->logger->addWriter($streamHandler);
}

ApplicationLogger::addWriter(object $writer) accepts every HandlerInterface implementation. The declared union is therefore narrower than what the bundle actually supports, and it rules out every Monolog handler that does not happen to extend StreamHandler: the AsyncAws CloudWatch handler, Sentry, Slack, Redis, and so on.

That ApplicationLoggerDb is already part of the union, and is not a StreamHandler, shows the intent was "a log writer", not "a stream".

A project cannot work around this. The return type of an overriding method may only be narrowed, never widened, so returning a non-stream handler is impossible. In our case the custom CloudWatch logger had to return null to satisfy the signature, which silently disabled process manager logging to CloudWatch: getLogger() drops a null writer without a warning.

Change

Widen the abstract return type to ?HandlerInterface, drop the two imports that become unused.

Backwards compatible. All four shipped implementations keep their current, narrower return types, which covariance allows:

  • File?StreamHandler
  • Console?StreamHandler
  • EmailSummary?StreamHandler
  • ApplicationApplicationLoggerDb

Project implementations that already return one of those types are unaffected.

The method name stays createStreamHandler() to avoid a breaking rename.

Branches

The same commit is proposed for pimcore12 in a separate PR, the file is identical on both branches.

The return value of AbstractLogger::createStreamHandler() is passed straight to
ApplicationLogger::addWriter(), which accepts every HandlerInterface implementation.
The narrower union StreamHandler|ApplicationLoggerDb|null therefore rules out valid
handlers for no reason, in particular every handler that does not write to a stream:
the AsyncAws CloudWatch handler, Sentry, Slack, Redis.

That the union already contains ApplicationLoggerDb, which is not a StreamHandler,
shows the intent was "a log writer", not "a stream".

Projects hitting this cannot return their handler at all, because the return type
cannot be widened in a child class. Widening it here to ?HandlerInterface is
backwards compatible: all existing implementations (File, Console, Application,
EmailSummary) keep their narrower return types, which covariance allows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant