laravel系统开发经验(五、日志系统)

纲要

  文章是关于在laravel环境下开发遇到的一些问题和处理方法的集合,会涉及方方面面,下面是关于日志的内容。

日志

  日志存在的主要目的是为了记录信息,包括备注信息和错误信息,便于后续追查。
  一般稍大的程序往往会出现很多意想不到的错误,特别是一些核心的错误,比如支付的钱不对,或者系统报错,这些需要及时地记录下来,有些甚至需要专门提醒自己。
  那么需求来了!
  1.laravel里面通过邮件给自己自动发送错误日志,如何实现?
 2.如何有多台服务器,如何实现日志的统一管理?

下面是针对两个问题的解决方案。

laravel如何集成邮件日志,出现系统错误自动给自己发送邮件?

1.首先配置日志,在app/config/logging.php里面配置下面的通道

         'email' => [
             'driver' => 'custom',
             'via' => App\Logging\EmailError::class,
             'level' => 'debug',
         ],
         //然后在默认的stack的channels添加一个邮件通道,那么当有错误发生的时候,会自动采用这一条通道来处理错误。
         'stack' => [
             'driver' => 'stack',
             'channels' => ['single','email'],
         ],


2.在app目录下,新建一个logging目录,新建下面的类EmailError.php,邮件错误日志,是集成的Swift_Mailer来处理邮件,原生的邮件类试了一下行不通。

 /**
  * 将日志以html形式同步到email里面--暂时只支持原生方法
  * Author: Haha
  */
 
 namespace App\Logging;
 use Monolog\Formatter\HtmlFormatter;
 use Monolog\Handler\SwiftMailerHandler;
 use Monolog\Logger;
 use Swift_Mailer;
 use Swift_SmtpTransport;
 use Swift_Message;
 class EmailError
 {
     /**
      * 日志通道定义
      * @param array $config 日志配置参数
      * @return Logger   一个日志通道实例
      */
     public function __invoke(array $config)
     {
         $transport = new Swift_SmtpTransport( config('mail.host'), config('mail.port'),config('mail.encryption'));
         $transport->setUsername(config('mail.username'));
         $transport->setPassword(config('mail.password'));
 
         $mailer =new Swift_Mailer($transport);
         $message =new  Swift_Message();
         $message->setFrom(array(config('mail.from.address') =>config('mail.from.name')));
         $message->setTo(config('mail.from.address'),config('mail.from.name'));
         $message->setSubject('IP:'.getLocalIP().' System-Error-Log'.date(' Y-m-d H:i:s',time()));
         return new Logger('email', [(new SwiftMailerHandler($mailer,$message,'ERROR',true))->setFormatter(new HtmlFormatter())]);
     }
 }


多台服务器,如何统一管理日志?

答案就是,通过redis来进行统一管理,或者通过mongodb来进行记录,也是可以的,但是不建议通过数据库来存储。因为日志数量多,而且日志的形式也比较多变,对于无结构的数据,采用关系型数据库来存储不是很适合。

1.首先配置日志,在app/config/logging.php里面配置下面的通道

         'redisLog' => [
             'driver' => 'custom',
             'via' => App\Logging\RedisError::class,
             'level' => 'debug',
         ],
         //然后在默认的stack的channels添加一个redis通道,那么当有错误发生的时候,会自动采用这一条通道来处理错误。
         'stack' => [
             'driver' => 'stack',
             'channels' => ['redisLog'],
         ],

2.在app目录下,新建一个logging目录,新建下面的类RedisError.php。
多台服务器,每一台的配置也许是一模一样的,为了区分来源,定义了一个全局函数getLocalIP()加上以天作为时间单位,用来区分是来源于那一台服务器哪一天产生的日志。

 /**
  * 将日志以json形式同步到redis里面
  * Author: Haha
  */
 
 namespace App\Logging;
 use Monolog\Handler\RedisHandler;
 use Monolog\Formatter\JsonFormatter;
 use Monolog\Logger;
 use Predis\Client;
 
 class RedisError
 {
     /**
      * 日志通道定义
      * @param array $config 日志配置参数
      * @return Logger   一个日志通道实例
      */
     public function __invoke(array $config)
         return new Logger('custom', [(new RedisHandler(new Client([
             'scheme' => 'tcp',
             'host' => config('database.redis.error.host', '192.168.0.83'),
             'port' => config('database.redis.error.port', 6379),
             'password' => config('database.redis.error.password', 'WoJiRedis666'),
             'database' => config('database.redis.error.database', 3),
         ]), 'System-Error-Log:'.getLocalIP().':'.date('Y-m-d',time()),'ERROR',true))->setFormatter(new JsonFormatter())]);
     }
 }



发表评论请留下您的大名
  • 最新评论
  • 总共0条评论