How to specify a separate file for logging INFO
in Laravel 5.1
?
Any immediate help will be highly appreciable. Thanks
Since Laravel >= 5.6 we can use Log Channels to make it work in a easy way. This allows you to create log channels which can be handled as own log files with own drivers, paths or levels. You just need this few lines to make it work.
config/logging.php:
return [
'channels' => [
'command' => [
'driver' => 'single',
'path' => storage_path('logs/command.log'),
'level' => 'debug',
],
],
];
Log where ever you want by parse the channel name:
Log::channel('command')->info('Something happened!');
A simple logger helper that allows you to log to multiple custom files on the fly. You can also add your custom handler and set the file path.
App\Helper\LogToChannels.php
<?php
/**
* Logger helper to log into different files
*
* @package App\Helpers
* @author Romain Laneuville <romain.laneuville@hotmail.fr>
*/
namespace App\Helpers;
use Monolog\Logger;
use Monolog\Handler\HandlerInterface;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;
/**
* Class LogToChannels
*
* @package App\Helpers
*/
class LogToChannels
{
/**
* The LogToChannels channels.
*
* @var Logger[]
*/
protected $channels = [];
/**
* LogToChannels constructor.
*/
public function __construct()
{
}
/**
* @param string $channel The channel to log the record in
* @param int $level The error level
* @param string $message The error message
* @param array $context Optional context arguments
*
* @return bool Whether the record has been processed
*/
public function log(string $channel, int $level, string $message, array $context = []): bool
{
// Add the logger if it doesn't exist
if (!isset($this->channels[$channel])) {
$handler = new StreamHandler(
storage_path() . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . $channel . '.log'
);
$handler->setFormatter(new LineFormatter(null, null, true, true));
$this->addChannel($channel, $handler);
}
// LogToChannels the record
return $this->channels[$channel]->{Logger::getLevelName($level)}($message, $context);
}
/**
* Add a channel to log in
*
* @param string $channelName The channel name
* @param HandlerInterface $handler The channel handler
* @param string|null $path The path of the channel file, DEFAULT storage_path()/logs
*
* @throws \Exception When the channel already exists
*/
public function addChannel(string $channelName, HandlerInterface $handler, string $path = null)
{
if (isset($this->channels[$channelName])) {
throw new \Exception('This channel already exists');
}
$this->channels[$channelName] = new Logger($channelName);
$this->channels[$channelName]->pushHandler(
new $handler(
$path === null ?
storage_path() . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . $channelName . '.log' :
$path . DIRECTORY_SEPARATOR . $channelName . '.log'
)
);
}
/**
* Adds a log record at the DEBUG level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function debug(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::DEBUG, $message, $context);
}
/**
* Adds a log record at the INFO level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function info(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::INFO, $message, $context);
}
/**
* Adds a log record at the NOTICE level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function notice(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::NOTICE, $message, $context);
}
/**
* Adds a log record at the WARNING level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function warn(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::WARNING, $message, $context);
}
/**
* Adds a log record at the WARNING level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function warning(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::WARNING, $message, $context);
}
/**
* Adds a log record at the ERROR level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function err(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::ERROR, $message, $context);
}
/**
* Adds a log record at the ERROR level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function error(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::ERROR, $message, $context);
}
/**
* Adds a log record at the CRITICAL level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function crit(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::CRITICAL, $message, $context);
}
/**
* Adds a log record at the CRITICAL level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return Boolean Whether the record has been processed
*/
public function critical(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::CRITICAL, $message, $context);
}
/**
* Adds a log record at the ALERT level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function alert(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::ALERT, $message, $context);
}
/**
* Adds a log record at the EMERGENCY level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function emerg(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::EMERGENCY, $message, $context);
}
/**
* Adds a log record at the EMERGENCY level.
*
* @param string $channel The channel name
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function emergency(string $channel, string $message, array $context = []): bool
{
return $this->log($channel, Logger::EMERGENCY, $message, $context);
}
}
App\Providers\LogToChannelsServiceProvider.php
<?php
/**
* Logger service provider to be abled to log in different files
*
* @package App\Providers
* @author Romain Laneuville <romain.laneuville@hotmail.fr>
*/
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Helpers\LogToChannels;
/**
* Class LogToChannelsServiceProvider
*
* @package App\Providers
*/
class LogToChannelsServiceProvider extends ServiceProvider
{
/**
* Initialize the logger
*
* @return void
*/
public function register()
{
$this->app->singleton('App\Helpers\LogToChannels', function () {
return new LogToChannels();
});
}
}
config\app.php (add the service provider)
// Register Service Providers
$app->register(App\Providers\LogToChannelsServiceProvider::class);
Then anywhere in your app you can call using dependency injection (add the class in your constructor and bind it to a log
class attribute)
$this->log->info('logger_name', 'Log message');
$this->log->error('other_logger_name', 'Log message', $someContext);
You can even customize your logger output by calling
$this->log->addChannel('channel_name', $customHandler);
And it will be accessible when you will call its name anywhere in your app.
Do you want to specifically log info
to one log file and another log type to another location? My solution might not help in that case, but could still be useful.
To write a log file to another location, use the method useDailyFiles
or useFiles
, and then info to log to the log file at the path you just specified. Like so:
Log::useDailyFiles(storage_path().'/logs/name-of-log.log');
Log::info([info to log]);
The first parameter for both methods is the path of the log file (which is created if it doesn't already exist) and for useDailyFiles
the second argument is the number of days Laravel will log for before erasing old logs. The default value is unlimited, so in my example I haven't entered a value.
In Laravel 5.6 you can create your own channel in config\logging.php
. If you have upgraded from an older Laravel version you need to create this file (https://laravel.com/docs/5.6/upgrade).
Add this to you channel array in config\logging.php
'your_channel_name' => [
'driver' => 'single',
'path' => storage_path('logs/your_file_name.log'),
],
You can then call any of the 8 logging levels like that:
Illuminate\Support\Facades\Log::channel('your_channel_name')->info('your_message');
The logs will be stored in logs/your_file_name.log
If you would like add another monolog handler, you may use the application's configureMonologUsing method.
Place a call to this method in bootstrap/app.php file right before the $app variable is returned:
$app->configureMonologUsing(function($monolog) {
$monolog->pushHandler(new StreamHandler('path/to/info.log', Logger::INFO, false)); // false value as third argument to disable bubbling up the stack
});
return $app;