126

So I have a Laravel controller:

class YeahMyController extends BaseController {
    public function getSomething() {
        Console::info('mymessage'); // <-- what do I put here?
        return 'yeahoutputthistotheresponse';
    }
}

Currently, I'm running the application using artisan (which runs PHP's built-in development web server under the hood):

php artisan serve

I would like to log console messages to the STDOUT pipe for the artisan process.

1
  • This is the best answer I've seen when you want to write to the Laravel log and display in the console: stackoverflow.com/a/50939811/470749 Commented May 18, 2019 at 12:19

17 Answers 17

153

Aha!

This can be done with the following PHP function:

error_log('Some message here.');

Found the answer here: Print something in PHP built-in web server

Sign up to request clarification or add additional context in comments.

6 Comments

more ideal is using laravel's built in logging ie, Log::info('This is some useful information.'); just see my answer
@wired00 The question specifically asks how to write to the artisan serve console. error_log() does so, while Log::info() does not.
just what I needed. quick 'n dirty - perfect for dev work
If you want the fancy command IO from Laravel (like styling, asking and table) then check the ConsoleCommand class in my answer here
But it's only printing strings i want to print an object :(
|
93

The question relates to serving via artisan and so Jrop's answer is ideal in that case. I.e, error_log logging to the apache log.

However, if your serving via a standard web server then simply use the Laravel specific logging functions:

\Log::info('This is some useful information.');

\Log::warning('Something could be going wrong.');

\Log::error('Something is really going wrong.');

Or with current version of Laravel, like this:

info('This is some useful information.');

This logs to Laravel's log file located at /laravel/storage/logs/laravel-<date>.log (laravel 5.0). Monitor the log - linux/osx: tail -f /laravel/storage/logs/laravel-<date>.log

4 Comments

There's no apache if you're using the artisan web server. And using Log::info will also not output to STDOUT.
@wired00 You are correct, but as stated in my original question, I was not using Apache, but was using the artisan web server. In that context, error_log is more useful.
@Jrop yep right you are, I amended my answer to clarify that
If you want the fancy command IO from Laravel (like styling, asking and table) then check the ConsoleCommand class in my answer here
47

I haven't tried this myself, but a quick dig through the library suggests you can do this:

$output = new \Symfony\Component\Console\Output\ConsoleOutput();
$output->writeln("<info>my message</info>");

I couldn't find a shortcut for this, so you would probably want to create a facade to avoid duplication.

4 Comments

Despite the fact that I like Jrop answers, I feel this should be the accepted answer too.
If you want the fancy command IO from Laravel (like styling, asking and table) then check the ConsoleCommand class in my answer here
output log style reference: info, comment, question, error and custom styles.
33

In Laravel 6 there is a channel called 'stderr'. See config/logging.php:

'stderr' => [
    'driver' => 'monolog',
    'handler' => StreamHandler::class,
    'formatter' => env('LOG_STDERR_FORMATTER'),
    'with' => [
        'stream' => 'php://stderr',
    ],
],

In your controller:

use Illuminate\Support\Facades\Log;

Log::channel('stderr')->info('Something happened!');

1 Comment

Just tried and it works like a charm! I added the LOG_CHANNEL in .env file to stderr and that's all I had to do
31

It's very simple.

You can call it from anywhere in APP.

$out = new \Symfony\Component\Console\Output\ConsoleOutput();
$out->writeln("Hello from Terminal");

1 Comment

Did you check it in terminal
12

For better explain Dave Morrissey's answer I have made these steps for wrap with Console Output class in a laravel facade.

1) Create a Facade in your prefer folder (in my case app\Facades):

class ConsoleOutput extends Facade {

 protected static function getFacadeAccessor() { 
     return 'consoleOutput';
 }

}

2) Register a new Service Provider in app\Providers as follow:

class ConsoleOutputServiceProvider extends ServiceProvider
{

 public function register(){
    App::bind('consoleOutput', function(){
        return new \Symfony\Component\Console\Output\ConsoleOutput();
     });
 }

}

3) Add all this stuffs in config\app.php file, registering the provider and alias.

 'providers' => [
   //other providers
    App\Providers\ConsoleOutputServiceProvider::class
 ],
 'aliases' => [
  //other aliases
   'ConsoleOutput' => App\Facades\ConsoleOutput::class,
 ],

That's it, now in any place of your Laravel application, just call your method in this way:

ConsoleOutput::writeln('hello');

Hope this help you.

1 Comment

If you want the fancy command IO from Laravel (like styling, asking and table) then check the ConsoleCommand class in my answer here
10

I wanted my logging information to be sent to stdout because it's easy to tell Amazon's Container service (ECS) to collect stdout and send it to CloudWatch Logs. So to get this working, I added a new stdout entry to my config/logging.php file like so:

    'stdout' => [
        'driver' => 'monolog',
        'handler' => StreamHandler::class,
        'with' => [
            'stream' => 'php://stdout',
        ],
        'level' => 'info',
    ],

Then I simply added 'stdout' as one of the channels in the stack log channel:

    'default' => env('LOG_CHANNEL', 'stack'),

    'stack' => [
        'driver' => 'stack',
        'channels' => ['stdout', 'daily'],
    ],

This way, I still get logs in a file for local development (or even on the instance if you can access it), but more importantly they get sent to the stdout which is saved in CloudWatch Logs.

Comments

8

If you want the fancy command IO from Laravel (like styling, asking and table) then I created this class below

Instructions

I have not fully verified everywhere that it is THE cleanest solution etc, but it works nice (but I only tested it from within a unit test case, under Laravel 5.5).

So most probably you can use it however you like:

$cmd = new ConsoleCommand;

$cmd->error("Aw snap!");
$cmd->table($headers, $rows);
$answer = $cmd->ask("Tell me, what do you need?");

//even Symfony's progress bar
$cmd->outputStyle->progressStart(5);  //set n = 100% (here 100% is 5 steps)
$cmd->outputStyle->progressAdvance(); //you can call it n times
$cmd->outputStyle->progressFinish();  //set to 100%

Or course you can also wrap in your own facade, or some static singleton etc, or anyway you wish.

The class itself

class ConsoleCommand extends \Illuminate\Console\Command
{
    protected $name = 'NONEXISTENT';
    protected $hidden = true;

    public $outputSymfony;
    public $outputStyle;

    public function __construct($argInput = null)
    {
        parent::__construct();

        $this->input = new \Symfony\Component\Console\Input\StringInput($argInput);

        $this->outputSymfony = new \Symfony\Component\Console\Output\ConsoleOutput();
        $this->outputStyle = new \Illuminate\Console\OutputStyle($this->input, $this->outputSymfony);

        $this->output = $this->outputStyle;
    }

}

1 Comment

Thanks for this nice idea. For current Laravel versions (using 7.x) I think it should be public function __construct($argInput = "") though.
4

If you want to log to STDOUT you can use any of the ways Laravel provides; for example (from wired00's answer):

Log::info('This is some useful information.');

The STDOUT magic can be done with the following (you are setting the file where info messages go):

Log::useFiles('php://stdout', 'info');

Word of caution: this is strictly for debugging. Do no use anything in production you don't fully understand.

1 Comment

This also works great for inline debugging of migrations and other artisan commands.
4

From Larave 6.0+

$this->info('This will appear in console');
$this->error('This error will appear in console');
$this->line('This line will appear in console);

Documentation https://laravel.com/docs/6.x/artisan#writing-output

2 Comments

this will work on console class but he is asking for controller
A quick fix would be return the output of the class method call it in the controller.
3

Bit late to this...I'm surprised that no one mentioned Symfony's VarDumper component that Laravel includes, in part, for its dd() (and lesser-known, dump()) utility functions.

$dumpMe = new App\User([ 'name' => 'Cy Rossignol' ]);

(new Symfony\Component\VarDumper\Dumper\CliDumper())->dump( 
    (new Symfony\Component\VarDumper\Cloner\VarCloner())->cloneVar($dumpMe)
);

There's a bit more code needed, but, in return, we get nice formatted, readable output in the console—especially useful for debugging complex objects or arrays:

App\User {#17
  #attributes: array:1 [
    "name" => "Cy Rossignol"
  ]
  #fillable: array:3 [
    0 => "name"
    1 => "email"
    2 => "password"
  ]
  #guarded: array:1 [
    0 => "*"
  ]
  #primaryKey: "id"
  #casts: []
  #dates: []
  #relations: []
  ... etc ...
}

To take this a step further, we can even colorize the output! Add this helper function to the project to save some typing:

function toConsole($var) 
{
    $dumper = new Symfony\Component\VarDumper\Dumper\CliDumper();
    $dumper->setColors(true);

    $dumper->dump((new Symfony\Component\VarDumper\Cloner\VarCloner())->cloneVar($var));
}

If we're running the app behind a full webserver (like Apache or Nginx—not artisan serve), we can modify this function slightly to send the dumper's prettified output to the log (typically storage/logs/laravel.log):

function toLog($var) 
{
    $lines = [ 'Dump:' ];
    $dumper = new Symfony\Component\VarDumper\Dumper\CliDumper();
    $dumper->setColors(true);
    $dumper->setOutput(function ($line) use (&$lines) { 
        $lines[] = $line;
    });

    $dumper->dump((new Symfony\Component\VarDumper\Cloner\VarCloner())->cloneVar($var));

    Log::debug(implode(PHP_EOL, $lines));
}

...and, of course, watch the log using:

$ tail -f storage/logs/laravel.log

PHP's error_log() works fine for quick, one-off inspection of simple values, but the functions shown above take the hard work out of debugging some of Laravel's more complicated classes.

1 Comment

I love this solution with CliDumper()! Thank you :)
2

Here's another way to go about it:

$stdout = fopen('php://stdout', 'w');
fwrite($stdout, 'Hello, World!' . PHP_EOL);

The PHP_EOL adds new line.

Comments

2

In command class

before class

use Symfony\Component\Console\Output\ConsoleOutput;

Inside the class methods

 $output = new ConsoleOutput();
 $output->writeln('my text that appears in command line ');

Comments

2

The other answers are not what I wanted, I found better answer form here: coloured-output-to-console-outside-commands

In any class that needs interaction with the console just use the trait InteractsWithIO and the ConsoleOutput class

use Illuminate\Console\Concerns\InteractsWithIO;
use Symfony\Component\Console\Output\ConsoleOutput;

class MyClass
{
    use InteractsWithIO;

    public function __construct()
    {
        $this->output = new ConsoleOutput();
    }

    public function myMethod(): void
    {
        $this->info('Say something green here');
        $this->comment('Say something yellow here');
        $this->erro('Ooops. My red error mesage');
    }
}

Comments

2

You have 3 options to write Log from controllers.

1. Laravel Log

use Illuminate\Support\Facades\Log;

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

This, will print the message to laravel.log, located on ./storage/logs/laravel.log

You can print string, object or array.

Even, you can use Log from blade templates:

{{ Log::info($img) }}

2. dump()

On your controller, you can put:

$test = "Testing dump() function.";
dump($test);

It will display on browser:

"Testing dump() function." // app/Http/Controllers/TestController.php:51

With this method, you can log string, objects, arrays.

3. error_log()

This built-in method sends a message to web server's error log:

$testMessage = "this is a test message";
error_log($testMessage);

this method also will show the message on laravel console, if you are running your app with artisan command, this message will show in this console.

It helps you if debugging and just want to see a messge, but don't want to save it in a log file.

Comments

1

You can use echo and prefix "\033", simple:

Artisan::command('mycommand', function () {
   echo "\033======== Start ========\n";
});

And change color text:

if (App::environment() === 'production') {
    echo "\033[0;33m======== WARNING ========\033[0m\n";
}

Comments

0

you should view your logs by using the following command before anything:

For Windows Get-Content -Path storage/logs/laravel.log -Wait

and after you run this command you will see that any route you navigate to and a method is called with a log method it will appear immediately.

you can use in your methods the below codes to log your message:

Log::info('your-message')

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.