用钉钉提醒 Laravel 11 异常:一个简单的实现 
                            
                                                    
                        
                    
                    
  
                    
                    受到这篇帖子启发,联想到自己也有 Error Tracking 的需求。我的项目目前只有 laravel.log 日志,不能主动提醒出错。之前调查过 Sentry、Laravel Flare 这样的专业服务,但最终没有使用。受上述帖子的启发,相比完全没有,自己实现一个简陋的解决方案总比没有强。
注册异常报告
- 使用 
dispatch()->afterResponse()可以在当前请求结束之后,再通知钉钉。 - 虽然是 dispatch,但这儿没有队列任务,并不需要队列运行。
 
// bootstrap/app.php
->withExceptions(function (Exceptions $exceptions) {
    if (App::environment('production')) {
        $exceptions->report(function (Exception $e) {
            // 等当前请求结束后,再发送到钉钉
            $message = Dingtalk::message($e);
            dispatch(function () use ($message) {
                Dingtalk::send($message);
            })->afterResponse();
        });
    }
})
发送消息到钉钉
- 使用钉钉的机器人 API 发送消息
 - 消息支持 Markdown 格式
 
// app/Dingtalk.php
class Dingtalk
{
    public static function sendException(Exception $e): void
    {
        static::send(static::message($e));
    }
    public static function message(Exception $e): array
    {
        return [
            'msgtype' => 'markdown',
            'markdown' => [
                'title' => 'Exception️',
                'text' => sprintf(
                    "# Exception: %s\n\n## File\n%s:%d\n\n## Trace\n%s",
                    $e->getMessage(),
                    $e->getFile(),
                    $e->getLine(),
                    Str::limit($e->getTraceAsString(), 200),
                ),
            ],
        ];
    }
    public static function send(array $message): void
    {
        $token = config('services.dingtalk.access_token');
        if (!$token) {
            throw new Exception('Dingtalk access token is not set');
        }
        $response = Http::post('https://oapi.dingtalk.com/robot/send?access_token=' . $token, $message);
        if ($response->failed()) {
            throw new Exception('Dingtalk message failed to send with status ' . $response->status());
        }
        if ($response->json('errcode') !== 0) {
            throw new Exception('Dingtalk message failed to send with error ' . $response->body());
        }
    }
}
别忘了配置钉钉 Token:
// config/services.php
'dingtalk' => [
    'access_token' => env('DINGTALK_ACCESS_TOKEN'),
],
测试效果
运行一个随机命令,比如:
$ php artisan xxx
   ERROR  Command "xxx" is not defined.
这是得到的结果:

           本帖已被设为精华帖!
        
      
                      本帖由 MArtian
        于 1年前 加精
            
                
          
                    
                    
          
          
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: