setChannel($channel); if (count($handlers) === 0) { $handlers[] = new StreamHandler('php://stdout'); } $this->handlers = $handlers; } public function getChannel(): ?string { return $this->channel; } public function setChannel(?string $value): void { $this->channel = ($value !== null) ? substr($value, 0, 29) : null; } public function getHandlers(): array { return $this->handlers; } /** System is unusable. */ public function emergency(string|\Stringable $message, array $context = []): void { $this->log(Level::Emergency->value, $message, $context); } /** Action must be taken immediately. */ public function alert(string|\Stringable $message, array $context = []): void { $this->log(Level::Alert->value, $message, $context); } /** * Critical conditions. * Example: Application component unavailable, unexpected exception. */ public function critical(string|\Stringable $message, array $context = []): void { $this->log(Level::Critical->value, $message, $context); } /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. */ public function error(string|\Stringable $message, array $context = []): void { $this->log(Level::Error->value, $message, $context); } /** Exceptional occurrences that are not errors. */ public function warning(string|\Stringable $message, array $context = []): void { $this->log(Level::Warning->value, $message, $context); } /** Normal but significant events. */ public function notice(string|\Stringable $message, array $context = []): void { $this->log(Level::Notice->value, $message, $context); } /** * Interesting events. * Example: User logs in, SQL logs. */ public function info(string|\Stringable $message, array $context = []): void { $this->log(Level::Info->value, $message, $context); } /** Detailed debug information. */ public function debug(string|\Stringable $message, array $context = []): void { $this->log(Level::Debug->value, $message, $context); } /** * Logs with an arbitrary level. * @throws \MensBeam\Logger\InvalidArgumentException */ public function log($level, string|\Stringable $message, array $context = []): void { // Because the interface won't allow limiting $level to just int|string this is // necessary. if (!is_int($level) && !is_string($level)) { $type = gettype($level); $type = ($type === 'object') ? $level::class : $type; throw new InvalidArgumentException(sprintf('Argument #1 ($level) must be of type int|string, %s given', $type)); } // If the level is a string convert it to a RFC5424 level integer. $origLevel = $level; $level = (is_string($level)) ? Level::fromPSR3($level) : $level; if ($level < 0 || $level > 7) { throw new InvalidArgumentException(sprintf('Invalid log level %s', $origLevel)); } # PSR-3: Logger Interface # ยง1.3 Context # # * Every method accepts an array as context data. This is meant to hold any # extraneous information that does not fit well in a string. The array can # contain anything. Implementors MUST ensure they treat context data with as # much lenience as possible. A given value in the context MUST NOT throw an # exception nor raise any php error, warning or notice. # # * If an Exception object is passed in the context data, it MUST be in the # 'exception' key. Logging exceptions is a common pattern and this allows # implementors to extract a stack trace from the exception when the log # backend supports it. Implementors MUST still verify that the 'exception' key # is actually an Exception before using it as such, as it MAY contain # anything. // We're not doing interpolation :) foreach ($this->handlers as $h) { $h($level, $this->channel, $message, $context); if (!$h->getOption('bubbles')) { break; } } } }