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

Artisan::output() returns empty string #36379

Closed
yoeriboven opened this issue Feb 24, 2021 · 10 comments
Closed

Artisan::output() returns empty string #36379

yoeriboven opened this issue Feb 24, 2021 · 10 comments

Comments

@yoeriboven
Copy link
Contributor

  • Laravel Version: 8.29.0
  • PHP Version: 7.4.12
  • Database Driver & Version:

Description:

I'm trying to write the output of (scheduled) commands to a log file.

I expect Artisan::output() to return the output. This only works when the command is called manually. This method returns an empty string when the command was called through the command line or scheduler.

Artisan uses the lastOutput property for this. This property is set in Artisan::call().

Running commands in the cli or through the scheduler doesn't call this command. These use the run() command.

Steps To Reproduce:

  1. Add a place to test
use Illuminate\Console\Events\CommandFinished;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Event;

Event::listen(function (CommandFinished $event) {
    dump('Artisan output: '. Artisan::output());

    // Here I could log the output
});
  1. Run a test from the cli and one from tinker

Manually
Schermafbeelding 2021-02-24 om 18 37 06

CLI
Schermafbeelding 2021-02-24 om 18 35 50

Possible solution:

If possible, set the lastOutput property in the run() method instead of call().

@taylorotwell
Copy link
Member

The CommandFinished event seems to already have an $output property?

$output = $event->output;

@driesvints
Copy link
Member

Been digging into this one but can't figure out why it's not working on the CLI. It seems the output buffer is cleared somehow before the process has ended.

@yoeriboven
Copy link
Contributor Author

@taylorotwell Before resorting to Artisan::output() I tried that. $event->output returns an instance of \Symfony\Component\Console\Output\OutputInterface and I can't seem to get string values out of that.

Optimal would be if $event->output returned some kind of string or an array of lines. Wouldn't fix this issue though.

@driesvints
Copy link
Member

driesvints commented Feb 25, 2021

@yoeriboven you can try to do the same thing the output method doet and check for a fetch method which you can call:

/**
 * Get the output for the last run command.
 *
 * @return string
 */
public function output()
{
    return $this->lastOutput && method_exists($this->lastOutput, 'fetch')
                    ? $this->lastOutput->fetch()
                    : '';
}

@driesvints
Copy link
Member

Nvm, doesn't seems to be available

@yoeriboven
Copy link
Contributor Author

@driesvints Yeah, tried that already... 😬

@yoeriboven
Copy link
Contributor Author

Probably because:

// Illuminate\Console\Application
$this->lastOutput; // returns \Symfony\Component\Console\Output\BufferedOutput

// Illuminate\Console\Events\CommandFinished
$event->output; // returns \Symfony\Component\Console\Output\OutputInterface

@driesvints
Copy link
Member

Yeah I just figured out that myself. I'm wondering why run and call have different fallbacks for the output implementation.

@taylorotwell
Copy link
Member

I'm not sure we have a great solution at the moment. Best advice I can give you right now is instead of scheduling the Artisan command directly schedule a callback which calls Artisan::call:

$schedule->call(function () {
    Artisan::call('inspire');
});

@taylorotwell
Copy link
Member

This should fix the problem: #36404

Will require updating your "artisan" file to use Illuminate\Console\BufferedConsoleOutput instead of just ConsoleOutput.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants