How to specify a separate file for logging INFO
in Laravel 5.1?

- 19,824
- 17
- 99
- 186

- 26,058
- 13
- 70
- 123
-
Possible duplicate of [Laravel Monolog. Log INFO level to separate file](http://stackoverflow.com/questions/32286010/laravel-monolog-log-info-level-to-separate-file) – Alex McCabe May 23 '16 at 09:36
-
Could you please verify the right answer again? It's outdated. Please check my answer and may mark it as right since its the common way in Laravel. – lin Feb 01 '21 at 11:50
6 Answers
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.

- 2,016
- 5
- 21
- 35
-
9This is still working in Laravel 5.4, I've just tested and used it. – user2094178 Apr 17 '17 at 04:07
-
1For problems/caveats with this approach see https://stackoverflow.com/a/32262707/96944 – Jannie Theunissen Nov 15 '17 at 10:04
-
Is there a way to remove second log handler after I wrote to log all I needed? – alekssaff Feb 13 '18 at 11:21
-
useDailyFiles() existed in Laravel 5.5, but not any more since 5.8 https://laravel.com/api/5.5/search.html?search=useDailyFiles https://laravel.com/api/5.8/search.html?search=useDailyFiles – PaulH Jun 22 '21 at 12:40
-
I guess this has been removed in Laravel 7. How to do this in Laravel 7 ? – Vagabond Feb 27 '23 at 07:44
Since 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

- 25,960
- 22
- 158
- 247
-
I also used the same. everything is working fine. but this file also storing other debug and error logs. why this happening. – Priyank lohan Oct 04 '19 at 04:50
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.
Simple add a new channel (choose your channel name, e.g. "command")
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!');

- 17,956
- 4
- 59
- 83
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.

- 457
- 3
- 13
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;

- 3,639
- 9
- 39
- 57
-
getting this error `PHP Fatal error: Class 'StreamHandler' not found in /var/www/html/project/bootstrap/app.php on line 56` – Debug Diva Sep 13 '15 at 18:00
-
4@RohitJindal swap `StreamHandler` out for `Monolog\Handler\StreamHandler`. You may also find you need to swap `Logger` out for `Monolog\Logger`, too. – alexrussell Sep 13 '15 at 19:36
-
1@alexrussell, so, according to it i have toinclude two namespaces in my bootstrap/app.php..`Monolog\Handler\StreamHandler` and `Monolog\Logger` ?? – Debug Diva Sep 14 '15 at 04:21
-
Yes, either `use` the namespaces, of reference the fully-qualified classes. – alexrussell Sep 14 '15 at 09:59
-
configureMonologUsing() existed in Laravel 5.5, but not any more since 5.8 https://laravel.com/api/5.5/search.html?search=configureMonologUsing https://laravel.com/api/5.8/search.html?search=configureMonologUsing – PaulH Jun 22 '21 at 12:42
If you want to separate only a set of logs you can do it using useFiles
method, as follows:
\Log::useFiles(storage_path() . '/logs/your_custom_log_file.log');
❗❗❗ But keep in mind that useFiles()
does not overwrite the default log handler, so the logs will be added to laravel.log
too.
In Laravel 5.4 when I need to create a log in a separate file, I fall back to file_put_contents
function:
$myLogInfo = "...";
file_put_contents(
storage_path() . '/logs/your_custom_log_file.log',
$myLogInfo . PHP_EOL,
FILE_APPEND | LOCK_EX
);

- 7,472
- 6
- 48
- 66