Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow easier Monolog config #14974

Merged
merged 12 commits into from
Nov 2, 2024
8 changes: 8 additions & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,19 @@
- Added `craft\filters\ConditionalFilterTrait`. ([#15948](https://github.com/craftcms/cms/pull/15948))
- Added `craft\filters\UtilityAccess`.
- Added `craft\helpers\UrlHelper::encodeUrl()`. ([#15838](https://github.com/craftcms/cms/issues/15838))
- Added `craft\log\MonologTarget::getAllowLineBreaks()`.
- Added `craft\log\MonologTarget::getFormatter()`.
- Added `craft\log\MonologTarget::getLevel()`.
- Added `craft\log\MonologTarget::getMaxFiles()`.
- Added `craft\log\MonologTarget::getName()`.
- Added `craft\log\MonologTarget::getProcessor()`.
- Added `craft\log\MonologTarget::getUseMicrosecondTimestamps()`.
- Added `craft\services\Addresses::EVENT_DEFINE_ADDRESS_COUNTRIES`. ([#15711](https://github.com/craftcms/cms/pull/15711))
- Added `craft\services\Addresses::getCountryList()`. ([#15711](https://github.com/craftcms/cms/pull/15711))
- Added `craft\services\Fields::EVENT_BEFORE_APPLY_FIELD_SAVE`. ([#15872](https://github.com/craftcms/cms/discussions/15872))
- Added `craft\web\View::registerCpTwigExtension()`.
- Added `craft\web\View::registerSiteTwigExtension()`.
- Improved support for creating log targets for third party logging services. ([#14974](https://github.com/craftcms/cms/pull/14974))
- Deprecated the `enableBasicHttpAuth` config setting. `craft\filters\BasicHttpAuthLogin` should be used instead. ([#15720](https://github.com/craftcms/cms/pull/15720))
- Added the `serializeForm` event to `Craft.ElementEditor`. ([#15794](https://github.com/craftcms/cms/discussions/15794))

Expand Down
119 changes: 107 additions & 12 deletions src/log/MonologTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Craft;
use craft\helpers\App;
use craft\helpers\ArrayHelper;
use DateTimeZone;
use Illuminate\Support\Collection;
use Monolog\Formatter\FormatterInterface;
Expand Down Expand Up @@ -81,18 +82,25 @@ class MonologTarget extends PsrTarget
*/
protected ?ProcessorInterface $processor = null;

/**
* @inheritdoc
*/
public function init(): void
public function __construct($config = [])
{
// Store and unset logger, so we can create it with a closure
$logger = ArrayHelper::remove($config, 'logger');

parent::__construct($config);

$this->formatter = $this->formatter ?? new LineFormatter(
format: "%datetime% [%channel%.%level_name%] [%extra.yii_category%] %message% %context% %extra%\n",
dateFormat: 'Y-m-d H:i:s',
allowInlineLineBreaks: $this->allowLineBreaks,
ignoreEmptyContextAndExtra: true,
);
$this->logger = $this->_createLogger($this->name);

$this->logger = match (true) {
$logger instanceof Logger => $logger,
is_callable($logger) => $logger($this),
default => $this->_createDefaultLogger(),
};
}

/**
Expand All @@ -101,7 +109,7 @@ public function init(): void
public function getLogger(): Logger
{
/** @var Logger */
return $this->logger;
return $this->logger ?? $this->_createDefaultLogger();
}

/**
Expand Down Expand Up @@ -171,10 +179,9 @@ private function _filterMessagesByPsrLevel(array $messages, string $level): arra
return $messages->all();
}

private function _createLogger(string $name): Logger
private function _createDefaultLogger(): Logger
{
$generalConfig = Craft::$app->getConfig()->getGeneral();
$logger = (new Logger($name))->useMicrosecondTimestamps($this->useMicrosecondTimestamps);
$logger = (new Logger($this->name))->useMicrosecondTimestamps($this->useMicrosecondTimestamps);

if ($this->processor) {
$logger->pushProcessor($this->processor);
Expand All @@ -190,18 +197,17 @@ private function _createLogger(string $name): Logger
Logger::WARNING,
bubble: false,
))->setFormatter($this->formatter));

$logger->pushHandler((new StreamHandler(
'php://stdout',
$this->level,
bubble: false,
))->setFormatter($this->formatter));
} else {
$logger->pushHandler((new RotatingFileHandler(
App::parseEnv(sprintf('@storage/logs/%s.log', $name)),
App::parseEnv(sprintf('@storage/logs/%s.log', $this->name)),
$this->maxFiles,
$this->level,
filePermission: $generalConfig->defaultFileMode,
filePermission: Craft::$app->getConfig()->getGeneral()->defaultFileMode,
))->setFormatter($this->formatter));
}

Expand All @@ -218,6 +224,19 @@ public function setName(string $name): void
}

/**
* Returns the log target’s name.
*
* @return string
* @since 4.13.0
*/
public function getName(): string
{
return $this->name;
}

/**
* Sets whether the log target should allow line breaks.
*
* @param bool $allowLineBreaks
* @throws InvalidConfigException
*/
Expand All @@ -227,6 +246,19 @@ public function setAllowLineBreaks(bool $allowLineBreaks): void
}

/**
* Returns whether the log target should allow line breaks.
*
* @return bool
* @since 4.13.0
*/
public function getAllowLineBreaks(): bool
{
return $this->allowLineBreaks;
}

/**
* Sets the log level.
*
* @param string|null $level
* @throws InvalidConfigException
*/
Expand All @@ -236,6 +268,19 @@ public function setLevel(?string $level): void
}

/**
* Returns the log level.
*
* @return string
* @since 4.13.0
*/
public function getLevel(): string
{
return $this->level;
}

/**
* Sets the maximum number of log files to store.
*
* @param int $maxFiles
* @throws InvalidConfigException
*/
Expand All @@ -245,6 +290,19 @@ public function setMaxFiles(int $maxFiles): void
}

/**
* Returns the maximum number of log files to store.
*
* @return int
* @since 4.13.0
*/
public function getMaxFiles(): int
{
return $this->maxFiles;
}

/**
* Sets whether logs should show microseconds in timestamps.
*
* @param bool $useMicrosecondTimestamps
* @throws InvalidConfigException
*/
Expand All @@ -254,6 +312,19 @@ public function setUseMicrosecondTimestamps(bool $useMicrosecondTimestamps): voi
}

/**
* Returns whether logs should show microseconds in timestamps.
*
* @return bool
* @since 4.13.0
*/
public function getUseMicrosecondTimestamps(): bool
{
return $this->useMicrosecondTimestamps;
}

/**
* Sets the log formatter.
*
* @param FormatterInterface|null $formatter
* @throws InvalidConfigException
*/
Expand All @@ -263,6 +334,19 @@ public function setFormatter(?FormatterInterface $formatter): void
}

/**
* Returns the log formatter.
*
* @return FormatterInterface|null
* @since 4.13.0
*/
public function getFormatter(): ?FormatterInterface
{
return $this->formatter;
}

/**
* Sets the log processor.
*
* @param ProcessorInterface|null $processor
* @throws InvalidConfigException
*/
Expand All @@ -271,6 +355,17 @@ public function setProcessor(?ProcessorInterface $processor): void
$this->_setLoggerProperty('processor', $processor);
}

/**
* Returns the log processor.
*
* @return ProcessorInterface|null
* @since 4.13.0
*/
public function getProcessor(): ?ProcessorInterface
{
return $this->processor;
}

/**
* @throws InvalidConfigException
*/
Expand Down