Получите весь вывод консоли из Symfony 5 OutputInterface - PullRequest
1 голос
/ 03 апреля 2020

У меня есть команда Symfony 5, подобная этой:

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

....

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this->input        = $input;
        $this->output       = $output;
        $this->io           = new SymfonyStyle($input, $output);
        ....
    }

Эта команда генерирует МНОГО выходных данных с $this->io->caution(...), $this->io->block(....), $this->io->text(....) и т. Д.

Иногда (не всегда: есть некоторые условия выполнения), в конце выполнения я хотел бы получить доступ к всему выводу , сгенерированному командой, и затем отправить его по электронной почте. Итак ... как я могу вернуть все, что показало OutputInterface? Есть ли какой-нибудь $this->output->getBuffer()?

У меня не было бы проблем поменяться OutputInterface $output с чем-то другим ( logger , может быть?), Если я все еще могу показать все на stdoutput (мой терминал), как я делаю в данный момент.

1 Ответ

2 голосов
/ 03 апреля 2020

Я не думаю, что есть что-то готовое, что выполнит sh это для вас. Вы можете достичь чего-то подобного с регистраторами ... но вам придется много поиграть с уровнями ошибок конфигурации, возможно, ввести более одного регистратора, вывод консоли никогда не совпадет с SymfonyStyle, et c.

Вам лучше строить свой дом, что не должно быть особенно трудным. Просто создайте что-нибудь, что обернет / украсит SymfonyStyle; и захватывает выходные данные.

Я предоставлю начальные строительные блоки, вы можете завершить sh реализацию:

class LoggingStyle
{
    private SymfonyStyle $style;
    private array        $logEntries = [];

    public function __construct(InputInterface $input, OutputInterface $output) {
        $this->style = new SymfonyStyle($input, $output);
    }

    private function addLog(string $type, string $message): void
    {
        $this->logEntries[] = [
            'type' => $type,
            'message' => $message,
            'time' => date('Y-m-d H:i:s')
        ];
    }

    public function flushLog():array
    {
        $log = $this->logEntries;
        $this->logEntries = [];

        return $log;
    }

    public function caution(string $message): void
    {
        $this->addLog('caution', $message);
        $this->style->caution($message);
    }

    public function text(string $message): void
    {
        $this->addLog('text', $message);
        $this->style->caution($message);
    }

    public function block(string $message): void
    {
        $this->addLog('block', $message);
        $this->style->caution($message);
    }
}

Вам нужно будет реализовать каждую часть SymfonyStyle интерфейс, который вам нужно использовать, и решить, как поступить с каким-то особым поведением, если оно вообще есть (например, с такими вещами, как ask(), table() или с индикаторами выполнения). Но это полностью зависит от вашей реализации.

А также решите, как отформатировать каждый из различных стилей вывода в вашей электронной почте, поскольку логически нет способа перевести его напрямую.

Вы может использовать этот класс напрямую, и если вы достигнете точки, где вам нужен агрегированный вывод, вы просто позвоните LoggingStyle::flushLog() и получите все записи в виде массива, чтобы вы могли обработать и отправить их соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...