laravel 5.2 custom log file for different tasks

后端 未结 10 1019
再見小時候
再見小時候 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

    App\Helpers\ChannelWriter.php

     [ 
                '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

    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])
    }
    

提交回复
热议问题