laravel 5.2 custom log file for different tasks

后端 未结 10 1018
再見小時候
再見小時候 2021-01-30 00:36

Can we create a custom log file for different purposes in laravel 5.2 like for order related log entries that should be in order.log and for payment related stuff the entry shou

相关标签:
10条回答
  • 2021-01-30 00:56

    Here you go... I've spent so much time to add custom functionality to Monolog which able to do THAT in a proper way. I tried sooooo many different ways, but all was a bit hacky. Finally I found a good way to get this functionality working....

    As the application is big, I needed separate log files, and maintain the existing Laravel's Log interface as much as possible. I needed something like:

    Log::write('audit', 'User logged in to the app.');
    Log::info('event', 'User sent out 2 emails.');

    The Solution:

    App\Providers\AppServiceProvider.php (add to register function)

    //Facade to Object binding
    $this->app->bind('chanellog', 'App\Helpers\ChannelWriter');
    

    config\app.php (add to aliases)

    //Custom Alias Class
    'ChannelLog' => App\Contracts\Facades\ChannelLog::class,
    

    App\Contracts\Facades\ChannelLog.php

    <?php
    
    namespace App\Contracts\Facades;
    
    use Illuminate\Support\Facades\Facade;
    
    /**
     * @see \Illuminate\Log\Writer
     */
    class ChannelLog extends Facade
    {
        /**
         * Get the registered name of the component.
         *
         * @return string
         */
        protected static function getFacadeAccessor()
        {
            return 'chanellog';
        }
    }
    

    App\Helpers\ChannelWriter.php

    <?php
    
    namespace App\Helpers;
    
    use Monolog\Logger;
    
    use App\Helpers\ChannelStreamHandler;
    
    class ChannelWriter
    {
        /**
         * The Log channels.
         *
         * @var array
         */
        protected $channels = [
            'event' => [ 
                'path' => 'logs/audit.log', 
                'level' => Logger::INFO 
            ],
            'audit' => [ 
                'path' => 'logs/audit.log', 
                'level' => Logger::INFO 
            ]
        ];
    
        /**
         * The Log levels.
         *
         * @var array
         */
        protected $levels = [
            'debug'     => Logger::DEBUG,
            'info'      => Logger::INFO,
            'notice'    => Logger::NOTICE,
            'warning'   => Logger::WARNING,
            'error'     => Logger::ERROR,
            'critical'  => Logger::CRITICAL,
            'alert'     => Logger::ALERT,
            'emergency' => Logger::EMERGENCY,
        ];
    
        public function __construct() {}
    
        /**
         * Write to log based on the given channel and log level set
         * 
         * @param type $channel
         * @param type $message
         * @param array $context
         * @throws InvalidArgumentException
         */
        public function writeLog($channel, $level, $message, array $context = [])
        {
            //check channel exist
            if( !in_array($channel, array_keys($this->channels)) ){
                throw new InvalidArgumentException('Invalid channel used.');
            }
    
            //lazy load logger
            if( !isset($this->channels[$channel]['_instance']) ){
                //create instance
                $this->channels[$channel]['_instance'] = new Logger($channel);
                //add custom handler
                $this->channels[$channel]['_instance']->pushHandler( 
                    new ChannelStreamHandler( 
                        $channel, 
                        storage_path() .'/'. $this->channels[$channel]['path'], 
                        $this->channels[$channel]['level']
                    )
                );
            }
    
            //write out record
            $this->channels[$channel]['_instance']->{$level}($message, $context);
        }
    
        public function write($channel, $message, array $context = []){
            //get method name for the associated level
            $level = array_flip( $this->levels )[$this->channels[$channel]['level']];
            //write to log
            $this->writeLog($channel, $level, $message, $context);
        }
    
        //alert('event','Message');
        function __call($func, $params){
            if(in_array($func, array_keys($this->levels))){
                return $this->writeLog($params[0], $func, $params[1]);
            }
        }
    
    }
    

    App\Helpers\ChannelStreamHandler.php

    <?php
    
    namespace App\Helpers;
    
    use Monolog\Handler\StreamHandler;
    
    /**
     * Use channels to log into separate files
     *
     * @author Peter Feher
     */
    class ChannelStreamHandler extends StreamHandler
    {
        /**
         * Channel name
         * 
         * @var String 
         */
        protected $channel;
    
        /**
         * @param String $channel Channel name to write
         * @see parent __construct for params
         */
        public function __construct($channel, $stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false)
        {
            $this->channel = $channel;
    
            parent::__construct($stream, $level, $bubble);
        }
    
        /**
         * When to handle the log record. 
         * 
         * @param array $record
         * @return type
         */
        public function isHandling(array $record)
        {
            //Handle if Level high enough to be handled (default mechanism) 
            //AND CHANNELS MATCHING!
            if( isset($record['channel']) ){
                return ( 
                    $record['level'] >= $this->level && 
                    $record['channel'] == $this->channel 
                );
            } else {
                return ( 
                    $record['level'] >= $this->level
                );
            }
        }
    
    }
    

    After this, you can do in any file:

    use ChannelLog as Log;
    ...
    function myFunction(){
        //Recommended (writes INFO to logs/event.log)
        Log::write('event', 'User sent out 3 voucher.')
        //Possible to use (writes ALERT to logs/audit.log)
        Log::alert('audit', 'User modified xyz entry.')
        //Or even: 
        Log::write('audit', 'User modified xyz entry.', ['user'=>1])
    }
    
    0 讨论(0)
  • 2021-01-30 01:00

    You can try repurposing the log functions to write different types of logs to different files. This can be done by editing the bootstrap/app.php file:

    $app->configureMonologUsing(function($monolog) {
        $bubble = false;
        $infoStreamHandler = new Monolog\Handler\StreamHandler( storage_path("/logs/orders.log"), Monolog\Logger::INFO, $bubble);
        $monolog->pushHandler($infoStreamHandler);
    
        $warningStreamHandler = new Monolog\Handler\StreamHandler( storage_path("/logs/logins.log"), Monolog\Logger::WARNING, $bubble);
        $monolog->pushHandler($warningStreamHandler);
    });
    

    Then in your code, you can do:

    Log::info('Order was created', ['ORDER-123']);
    
    Log::warning('User login', ['USER-1']);
    

    You can use this method to edit all the available log functions:

    • DEBUG
    • INFO
    • NOTICE
    • WARNING
    • ERROR
    • CRITICAL
    • ALERT
    • EMERGENCY
    0 讨论(0)
  • 2021-01-30 01:03

    This is supported in a much easier way now

    1. Create a channel

      goto: root/config/logging.php, under channels array add your custom channel i.e

          'payments' => [
              'driver' => 'single',
              'path' => storage_path('logs/payments.log'),
              'level' => 'info',
        ],
    
    1. In your route or controller write to this log
        Log::channel('payments')->info('A transaction has been made!');
    
    1. The payment logs can be found at /storage/logs/payments.log

    NOTE: extendible to enhance furthur your requirements

    Laravel version 5.6 Docs

    0 讨论(0)
  • 2021-01-30 01:06

    I managed my own log function which can be put in helper.php file in app dir.

    if ( ! function_exists( 'write_log' ) ) {
        /**
         * Write log to log file
         *
         * @param string|array|object $log
         */
        function write_log( $log ) {
            if ( env('APP_LOG_LEVEL', 'debug') == 'debug' ) {
                if ( is_array( $log ) || is_object( $log ) ) {
                    file_put_contents(laravelInstallDir().'../debug.log', print_r( $log, true ), FILE_APPEND);
                } else {
                    file_put_contents(laravelInstallDir().'../debug.log', $log, FILE_APPEND);
                }
            }
        }
    }
    

    Please adjust the path laravelInstallDir().'../debug.log' as need

    0 讨论(0)
提交回复
热议问题