parent
01a7d7ffc4
commit
de43de4ca0
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace jrosset\CliProgram\Monolog;
|
||||||
|
|
||||||
|
use jrosset\ExtendedMonolog\ExceptionLogger;
|
||||||
|
use jrosset\ExtendedMonolog\LogDirectoryHandler;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation for an application with a {@see ConsoleOutputWithMonolog} and a {@see LogDirectoryHandler Monolog log directory} for each command
|
||||||
|
*/
|
||||||
|
trait TMonologApplication {
|
||||||
|
/**
|
||||||
|
* @var string The main log directory for Monolog: on subdirectory by command
|
||||||
|
*/
|
||||||
|
private string $logMainDirectory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
protected function getOutputInterfaceForCommand (Command $command, InputInterface $input, OutputInterface $output): OutputInterface {
|
||||||
|
return new ConsoleOutputWithMonolog(
|
||||||
|
$output,
|
||||||
|
new ExceptionLogger(
|
||||||
|
$command->getName(),
|
||||||
|
[
|
||||||
|
new LogDirectoryHandler(
|
||||||
|
$this->getLogMainDirectory() . DIRECTORY_SEPARATOR
|
||||||
|
. str_replace(':', DIRECTORY_SEPARATOR, $command->getName())
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main log directory for Monolog: on subdirectory by command
|
||||||
|
*
|
||||||
|
* @return string The main log directory for Monolog: on subdirectory by command
|
||||||
|
*/
|
||||||
|
public function getLogMainDirectory (): string {
|
||||||
|
return $this->logMainDirectory;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set the main log directory for Monolog: on subdirectory by command
|
||||||
|
*
|
||||||
|
* @param string $logMainDirectory The main log directory for Monolog: on subdirectory by command
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setLogMainDirectory (string $logMainDirectory): self {
|
||||||
|
$this->logMainDirectory = $logMainDirectory;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -1,76 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace jrosset\CliProgram\Monolog;
|
|
||||||
|
|
||||||
use Monolog\Logger;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a {@see LoggerInterface Monolog Logger} for {@see OutputInterface}
|
|
||||||
*/
|
|
||||||
trait TOutputInterfaceWithMonolog {
|
|
||||||
/**
|
|
||||||
* @var LoggerInterface|null The logger
|
|
||||||
*/
|
|
||||||
private ?LoggerInterface $logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger
|
|
||||||
*
|
|
||||||
* @return LoggerInterface|null The logger
|
|
||||||
*/
|
|
||||||
public function getLogger (): ?LoggerInterface {
|
|
||||||
return $this->logger;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Set the logger
|
|
||||||
*
|
|
||||||
* @param LoggerInterface|null $logger The logger
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function setLogger (?LoggerInterface $logger): self {
|
|
||||||
$this->logger = $logger;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function write($messages, bool $newline = false, int $options = 0): void {
|
|
||||||
if (!is_iterable($messages)) {
|
|
||||||
$messages = [$messages];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->logger !== null && (($options & ConsoleOutputWithMonolog::OPTION_SKIP_MONOLOG) !== ConsoleOutputWithMonolog::OPTION_SKIP_MONOLOG)) {
|
|
||||||
$verbosities = OutputInterface::VERBOSITY_QUIET | OutputInterface::VERBOSITY_NORMAL | OutputInterface::VERBOSITY_VERBOSE | OutputInterface::VERBOSITY_VERY_VERBOSE | OutputInterface::VERBOSITY_DEBUG;
|
|
||||||
$verbosity = $verbosities & $options ?: OutputInterface::VERBOSITY_NORMAL;
|
|
||||||
|
|
||||||
if ($verbosity <= OutputInterface::VERBOSITY_QUIET) {
|
|
||||||
$loggerLevel = Logger::ERROR;
|
|
||||||
}
|
|
||||||
elseif ($verbosity <= OutputInterface::VERBOSITY_NORMAL) {
|
|
||||||
$loggerLevel = Logger::NOTICE;
|
|
||||||
}
|
|
||||||
elseif ($verbosity <= OutputInterface::VERBOSITY_VERBOSE) {
|
|
||||||
$loggerLevel = Logger::INFO;
|
|
||||||
}
|
|
||||||
elseif ($verbosity <= OutputInterface::VERBOSITY_VERY_VERBOSE) {
|
|
||||||
$loggerLevel = Logger::INFO;
|
|
||||||
}
|
|
||||||
elseif ($verbosity <= OutputInterface::VERBOSITY_DEBUG) {
|
|
||||||
$loggerLevel = Logger::DEBUG;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$loggerLevel = Logger::NOTICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($messages as $message) {
|
|
||||||
$this->logger->log($loggerLevel, strip_tags($message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::write($messages, $newline, $options);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,130 @@
|
|||||||
|
<?php
|
||||||
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
|
namespace jrosset\CliProgram\Output;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A generic output interface with a {@see LoggerInterface PSR logger} connected
|
||||||
|
*
|
||||||
|
* @template TLogger of LoggerInterface
|
||||||
|
*/
|
||||||
|
class OutputWithLogger extends OutputWrapper {
|
||||||
|
/**
|
||||||
|
* Option to not write messages to logger
|
||||||
|
*
|
||||||
|
* @see static::write()
|
||||||
|
* @see static::writeln()
|
||||||
|
*/
|
||||||
|
public const OPTION_SKIP_LOGGER = 4096;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var TLogger|null The logger
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization
|
||||||
|
*
|
||||||
|
* @param OutputInterface $output The real output interface
|
||||||
|
* @param TLogger|null $logger The logger
|
||||||
|
*
|
||||||
|
* @noinspection PhpMissingParamTypeInspection
|
||||||
|
*/
|
||||||
|
public function __construct (OutputInterface $output, $logger = null) {
|
||||||
|
parent::__construct($output);
|
||||||
|
$this->setLogger($logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger
|
||||||
|
*
|
||||||
|
* @return TLogger|null The logger
|
||||||
|
*/
|
||||||
|
public function getLogger () {
|
||||||
|
return $this->logger;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set the logger
|
||||||
|
*
|
||||||
|
* @param TLogger|null $logger The logger
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException If the logger is not null or an instance for {@see LoggerInterface}
|
||||||
|
*
|
||||||
|
* @noinspection PhpMissingParamTypeInspection
|
||||||
|
*/
|
||||||
|
public function setLogger ($logger): self {
|
||||||
|
if ($logger !== null && !$logger instanceof LoggerInterface) {
|
||||||
|
throw new InvalidArgumentException('The logger must be null or a ' . LoggerInterface::class . ' instance');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger = $logger;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write into the logger
|
||||||
|
*
|
||||||
|
* @param iterable|string $messages The messages to write
|
||||||
|
* @param bool $newline Newline at the end ?
|
||||||
|
* @param int $options A bitmask of options
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @noinspection PhpUnusedParameterInspection
|
||||||
|
*/
|
||||||
|
protected function writeToLogger ($messages, bool $newline = false, int $options = 0): void {
|
||||||
|
if ($this->logger === null || ($options & static::OPTION_SKIP_LOGGER) === static::OPTION_SKIP_LOGGER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//region Calcul log level
|
||||||
|
$verbosities = OutputInterface::VERBOSITY_QUIET
|
||||||
|
| OutputInterface::VERBOSITY_NORMAL
|
||||||
|
| OutputInterface::VERBOSITY_VERBOSE
|
||||||
|
| OutputInterface::VERBOSITY_VERY_VERBOSE
|
||||||
|
| OutputInterface::VERBOSITY_DEBUG;
|
||||||
|
$loggerLevel = $this->getLoggerLevelFromVerbosity(
|
||||||
|
$verbosities & $options ? : OutputInterface::VERBOSITY_NORMAL
|
||||||
|
);
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
if (!is_iterable($messages)) {
|
||||||
|
$messages = [$messages];
|
||||||
|
}
|
||||||
|
foreach ($messages as $message) {
|
||||||
|
$this->getLogger()->log($loggerLevel, strip_tags($message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* OGet the logger level from verbosity
|
||||||
|
*
|
||||||
|
* @param int $verbosity The verbosity
|
||||||
|
*
|
||||||
|
* @return mixed The logger level
|
||||||
|
* @noinspection PhpReturnDocTypeMismatchInspection
|
||||||
|
*/
|
||||||
|
protected function getLoggerLevelFromVerbosity (int $verbosity) {
|
||||||
|
return $verbosity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function write ($messages, bool $newline = false, int $options = 0) {
|
||||||
|
$this->writeToLogger($messages, $newline, $options);
|
||||||
|
return parent::write($messages, $newline, $options);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function writeLn ($messages, int $options = 0) {
|
||||||
|
$this->writeToLogger($messages, true, $options);
|
||||||
|
return parent::writeLn($messages, $options);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace jrosset\CliProgram\Output;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper for an OutputInterface
|
||||||
|
*/
|
||||||
|
abstract class OutputWrapper implements OutputInterface {
|
||||||
|
/**
|
||||||
|
* @var OutputInterface The real output interface
|
||||||
|
*/
|
||||||
|
private OutputInterface $output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization
|
||||||
|
*
|
||||||
|
* @param OutputInterface $output The real output interface
|
||||||
|
*/
|
||||||
|
public function __construct (OutputInterface $output) {
|
||||||
|
$this->output = $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The real output interface
|
||||||
|
*
|
||||||
|
* @return OutputInterface The real output interface
|
||||||
|
*/
|
||||||
|
public function getOutput (): OutputInterface {
|
||||||
|
return $this->output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function write ($messages, bool $newline = false, int $options = 0) {
|
||||||
|
return $this->getOutput()->write($messages, $newline, $options);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function writeln ($messages, int $options = 0) {
|
||||||
|
return $this->getOutput()->writeln($messages, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function setVerbosity (int $level) {
|
||||||
|
return $this->getOutput()->setVerbosity($level);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getVerbosity (): int {
|
||||||
|
return $this->getOutput()->getVerbosity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function isQuiet (): bool {
|
||||||
|
return $this->getOutput()->isQuiet();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function isVerbose (): bool {
|
||||||
|
return $this->getOutput()->isVerbose();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function isVeryVerbose (): bool {
|
||||||
|
return $this->getOutput()->isVeryVerbose();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function isDebug (): bool {
|
||||||
|
return $this->getOutput()->isDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function setDecorated (bool $decorated) {
|
||||||
|
return $this->getOutput()->setDecorated($decorated);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function isDecorated (): bool {
|
||||||
|
return $this->getOutput()->isDecorated();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
* @noinspection PhpInappropriateInheritDocUsageInspection
|
||||||
|
*/
|
||||||
|
public function setFormatter (OutputFormatterInterface $formatter) {
|
||||||
|
return $this->getOutput()->setFormatter($formatter);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getFormatter (): OutputFormatterInterface {
|
||||||
|
return $this->getOutput()->getFormatter();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace jrosset\CliProgram\Output;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation for an application with a by-command {@see OutputInterface}
|
||||||
|
*/
|
||||||
|
trait TCommandOutputApplication {
|
||||||
|
/**
|
||||||
|
* Get the {@see OutputInterface} for a command
|
||||||
|
*
|
||||||
|
* @param Command $command The command
|
||||||
|
* @param InputInterface $input The input
|
||||||
|
* @param OutputInterface $output The existing output
|
||||||
|
*
|
||||||
|
* @return OutputInterface The output for the command
|
||||||
|
*
|
||||||
|
* @throws Throwable On error
|
||||||
|
*
|
||||||
|
* @noinspection PhpUnusedParameterInspection
|
||||||
|
*/
|
||||||
|
protected function getOutputInterfaceForCommand (Command $command, InputInterface $input, OutputInterface $output): OutputInterface {
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
|
protected function doRunCommand (Command $command, InputInterface $input, OutputInterface $output): int {
|
||||||
|
return parent::doRunCommand($command, $input, $this->getOutputInterfaceForCommand($command, $input, $output));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue