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.
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
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
Laravel 5.0 http://laravel.com/docs/5.0/errors
Laravel 4.2: http://laravel.com/docs/4.2/errors
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.
It's very simple.
You can call it from anywhere in APP.
$out = new \Symfony\Component\Console\Output\ConsoleOutput();
$out->writeln("Hello from Terminal");
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!');
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.
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;
}
}
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.
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.
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.
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.
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 ');
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";
}
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
Related
I would like to separate Tests and Data Providers. Using PHP 8 attributes, I cannot get the following test to run when referencing an external Data Provider:
#[Test]
#[DataProviderExternal(RouterDataProvider::class, 'registerGetRouteData')]
public function itRegistersGetRoute(Route $route, array $expectedResult)
{
$this->router->get($route);
$this->assertEquals($expectedResult, $this->router->getRoutes());
}
My data provider class:
class RouterDataProvider
{
public static function registerGetRouteData(): array
{
return [
$route = new Route('/', ['IndexController', 'index']),
[
'GET' => [
'/' => $route,
],
'POST' => []
]
];
}
}
How could I get this test to run with the desired provider method?
By running PHPUnit with the following flags, I was able to see exactly what my issue was:
./vendor/bin/phpunit --display-deprecations --display-warnings --diplay-errors --display-notices
The data set was invalid. Changing the return to yield and updating the return type for the registerGetRouteData method from array to \Generator resolved this.
I was running phpunit with the --testdox flag, so I'm not sure if this is what stopped me seeing any errors initially and assume the test was being skipped.
We're using Symfony Messenger in a Symfony 5 project to integrate with RabbitMQ. It works fine when sending messages within Symfony, but I need the ability to use the Messenger component to send messages from some legacy PHP applications that are not built with the Symfony framework.
Under Symfony, it handles all the magic by injecting the MessageBusInterface and all I need to do is something like this:
public function processTestMessage(MessageBusInterface $bus)
{
$bus->dispatch(new TestMessage('Hello World!');
}
I need to somehow instantiate my own version of $bus that will send AMQP messages the same way that Symfony does. I've been trying to recreate everything that Symfony does behind the scenes to accomplish this, but have not been able to put all the details together.
The crux of the problem is to create my own SendMessageMiddleware that does the same thing as Symfony. After that, it's simple:
$sendersLocator = ???
$eventDispatcher = ???
$sendMessageMiddleware = new($sendersLocator, $eventDispatcher);
$bus = new MessageBus([$sendMessageMiddleware]);
Does anyone have any examples of working code that uses the Messenger component to send AMQP messages outside of Symfony?
This can be improved but it works for me:
use Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpSender;
use Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\Middleware\SendMessageMiddleware;
use Symfony\Component\Messenger\Transport\Sender\SendersLocatorInterface;
$sendersLocator = new class implements SendersLocatorInterface {
public function getSenders(Envelope $envelope): iterable
{
$connection = new Connection(
[
'hosts' => 'localhost',
'port' => 5672,
'vhosts' => '/',
'login' => 'guest',
'password' => 'guest'
],
[
'name' => 'messages'
],
[
'messages' => []
]
);
return [
'async' => new AmqpSender($connection)
];
}
};
$middleware = new SendMessageMiddleware($sendersLocator);
$bus = new MessageBus([$middleware]);
$bus->dispatch(new MyMessage());
I modified the above answer to let me pass the RabbitMQ credentials as an environment variable. This is what I needed for my application. I was trying to write my own DSN parser and discovered that Symfony already does it, so I basically lifted the code from there.
If the environment variable is not set, it defaults to use the same settings shown in the example above.
use Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpSender;
use Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\Middleware\SendMessageMiddleware;
use Symfony\Component\Messenger\Transport\Sender\SendersLocatorInterface;
$sendersLocator = new class implements SendersLocatorInterface {
public function getSenders(Envelope $envelope): iterable
{
$dsn = getenv('MESSENGER_TRANSPORT_DSN') ?: $_ENV['MESSENGER_TRANSPORT_DSN'];
$connection = Connection::fromDsn($dsn);
return [
'async' => new AmqpSender($connection)
];
}
};
$middleware = new SendMessageMiddleware($sendersLocator);
$bus = new MessageBus([$middleware]);
$bus->dispatch(new MyMessage());
I'm trying to create a customised command for my first time with Symfony.
This command should execute 3 commands in one go.
This is my command class
class DoctrineFullFixturesLoadCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('doctrine:full-fixtures:load')
->setDescription('...')
->addArgument('argument', InputArgument::OPTIONAL, 'Argument description')
->addOption('option', null, InputOption::VALUE_NONE, 'Option description')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$argument = $input->getArgument('argument');
if ($input->getOption('option')) {
// ...
}
$arrCommands = [
[
'command' => 'doctrine:database:drop',
'--force' => true
], [
'command' => 'doctrine:database:create'
], [
'command' => 'doctrine:schema:update',
'--force' => true,
'--complete' => true
]
];
foreach ($arrCommands as $arrInput) {
$this->getApplication()->run(
new ArrayInput($arrInput),
$output
);
}
$output->writeln('Command result.');
}
}
The issue occurs when the iteration starts.
It is actually executed only the first command in the line instead of all three.
It seems the iteration stops after executing the first command for some reason, which I don't understand, in fact the method at the end $output->writeln, isn't called at all.
You should enable the debug for the console to understand the problem.
Console commands run in the environment defined in the APP_ENV variable of the .env file, which is dev by default. It also reads the APP_DEBUG value to turn "debug" mode on or off (it defaults to 1, which is on).
To run the command in another environment or debug mode, edit the value of APP_ENV and APP_DEBUG.
I have created a console command in console/controllers with SuggestionController .
If i run command like php yii suggestions, its working.
I want to know how to execute console command from web without any extensions of yii2.
It can be done much simpler
$oldApp = \Yii::$app;
new \yii\console\Application([
'id' => 'Command runner',
'basePath' => '#app',
'components' => [
'db' => $oldApp->db,
],
);
\Yii::$app->runAction('migrate/up', ['migrationPath' => '#yii/rbac/migrations/', 'interactive' => false]);
\Yii:$app = $oldApp;
Github LINK
As of Yii2 - 2.0.11.2 advanced app -- this works
First let's make sure controller and namespace correct. In this case frontend app accessing console application import method()
In console\controllers\FhirController
Set the alias to be available in the console\config\main.php [OPTIONAL]
'aliases' => [
'#common' => dirname(__DIR__),
'#frontend' => dirname(dirname(__DIR__)) . '/frontend',
'#backend' => dirname(dirname(__DIR__)) . '/backend',
'#console' => dirname(dirname(__DIR__)) . '/console',
],
Finally from the frontend view, make the call like this:
In this case, calling the controller route fhir then method import()
$consoleController = new console\controllers\FhirController('fhir', Yii::$app);
$consoleController->runAction('import');
On a site I'm overhauling, I have a need for a background task, that can be toggled via an action, which requires that I can also find its pid using ps. After much googling and almost as much swearing, I pieced together the solution.
# First change to (already-calculated) correct dir:
chdir($strPath);
# Now execute with nohup, directed to dev/null, and crucially with & at end, to run async:
$output = shell_exec("nohup php yii <console controller>/<action> > /dev/null &");
Yes, I understand that shell_exec should be used with extreme caution, thanks.
This is way I found and used some time ago to run yii console controller/action (I used this for run migrations from web).
In your web controller action:
// default console commands outputs to STDOUT
// so this needs to be declared for wep app
if (! defined('STDOUT')) {
define('STDOUT', fopen('/tmp/stdout', 'w'));
}
$consoleController = new \yii\console\controllers\SuggestionController;
$consoleController->runAction('your action eg. index');
/**
* open the STDOUT output file for reading
*
* #var $message collects the resulting messages of the migrate command to be displayed in a view
*/
$handle = fopen('/tmp/stdout', 'r');
$message = '';
while (($buffer = fgets($handle, 4096)) !== false) {
$message .= $buffer . "\n";
}
fclose($handle);
return $message;
You can either exec() your command ´´´php yii suggestions´´´ but this may result in permission issues with the webserver user.
The better way is to use a ConsoleRunner extension, e.g. yii2-console-runner or yii2-console-runner-extension which do the job control job a little bit more sophisticated and more secure with popen().
Always be aware of code injections when executing exec() and the like!
I think this is the simplest solution:
$controller = new SuggestionController(Yii::$app->controller->id, Yii::$app);
$controller->actionSuggestions();
yii2 call console command from web or api .
my controller name :
UnitController
in folder
console/controllers
my action name :
actionUnitDesc
if(!defined('STDIN')) define('STDIN', fopen('php://stdin', 'rb'));
if(!defined('STDOUT')) define('STDOUT', fopen('php://stdout', 'wb'));
if(!defined('STDERR')) define('STDERR', fopen('php://stderr', 'wb'));
$consoleController = new \console\controllers\UnitController('unit', Yii::$app);
$consoleController->runAction('unit-des');
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.
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
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
Laravel 5.0 http://laravel.com/docs/5.0/errors
Laravel 4.2: http://laravel.com/docs/4.2/errors
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.
It's very simple.
You can call it from anywhere in APP.
$out = new \Symfony\Component\Console\Output\ConsoleOutput();
$out->writeln("Hello from Terminal");
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!');
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.
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;
}
}
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.
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.
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.
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.
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 ');
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";
}
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