From d77c6beac79ec4390fdbf24822a22ef8daa7735b Mon Sep 17 00:00:00 2001 From: testadmin Date: Thu, 14 May 2026 11:28:33 +0800 Subject: [PATCH] feat: add logging module for backend + frontend error reporting Backend: - New Logger utility (app/utils/Logger.php) with category-based log files (connect/game/bet/error/frontend under runtime/log/) - Log WebSocket connect/close events (WsConnect, WsClose) - Log dealer auth success/failure (SpaceConnectService) - Log all game events: startBet, endBet, changeBoot, opening for all 7 game types - Log unhandled exceptions (ExceptionHandle) - Separate SQL/error logs via apart_level, enable realtime_write for Swoole - Add /log/report POST endpoint for frontend error ingestion Frontend: - New error-report.js with window.onerror + unhandledrejection auto-reporting - Added to all 12 dealer HTML templates - Bump VERSION_V to v10.1.0 --- app/ExceptionHandle.php | 8 +++- app/common.php | 2 +- app/handle/view/index/tab_b.html | 1 + app/handle/view/index/tab_b_auto.html | 1 + app/handle/view/index/tab_b_sb.html | 1 + app/handle/view/index/tab_dice.html | 1 + app/handle/view/index/tab_dt.html | 1 + app/handle/view/index/tab_dt_auto.html | 1 + app/handle/view/index/tab_dt_sb.html | 1 + app/handle/view/index/tab_knn.html | 1 + app/handle/view/index/tab_nn.html | 1 + app/handle/view/index/tab_nn_sb.html | 1 + app/handle/view/index/tab_roulette.html | 1 + app/handle/view/index/tab_toning.html | 1 + app/listener/WsClose.php | 3 +- app/listener/WsConnect.php | 6 +++ app/listener/space/ChangeBoot.php | 3 ++ app/services/connect/SpaceConnectService.php | 5 +- .../opening/OpeningBaccaratService.php | 3 ++ app/services/opening/OpeningDiceService.php | 3 ++ app/services/opening/OpeningDtService.php | 3 ++ app/services/opening/OpeningNnService.php | 3 ++ .../opening/OpeningRouletteService.php | 3 ++ app/services/opening/OpeningTcService.php | 3 ++ app/services/opening/OpeningToningService.php | 3 ++ app/services/process/EndBetService.php | 3 ++ app/services/process/StartBetService.php | 3 ++ app/utils/Logger.php | 40 ++++++++++++++++ config/log.php | 6 +-- public/static/handle/js/error-report.js | 47 +++++++++++++++++++ route/app.php | 16 +++++++ 31 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 app/utils/Logger.php create mode 100644 public/static/handle/js/error-report.js diff --git a/app/ExceptionHandle.php b/app/ExceptionHandle.php index 453d126..ad8ac07 100644 --- a/app/ExceptionHandle.php +++ b/app/ExceptionHandle.php @@ -36,7 +36,13 @@ class ExceptionHandle extends Handle */ public function report(Throwable $exception): void { - // 使用内置的方式记录异常日志 + if (!$this->isIgnoreReport($exception)) { + \app\utils\Logger::error(\app\utils\Logger::CAT_ERROR, $exception->getMessage(), [ + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + 'trace' => substr($exception->getTraceAsString(), 0, 2000), + ]); + } parent::report($exception); } diff --git a/app/common.php b/app/common.php index ee81690..5139cdc 100644 --- a/app/common.php +++ b/app/common.php @@ -3,7 +3,7 @@ //应用公共文件 // 版本号 -define('VERSION_V','?ver=v10.0.9'); +define('VERSION_V','?ver=v10.1.0'); // 强制加载中文语言包 \think\facade\Lang::load(__DIR__ . '/lang/zh-cn.php'); diff --git a/app/handle/view/index/tab_b.html b/app/handle/view/index/tab_b.html index caf023f..a502aa7 100644 --- a/app/handle/view/index/tab_b.html +++ b/app/handle/view/index/tab_b.html @@ -292,6 +292,7 @@ + \ No newline at end of file diff --git a/app/handle/view/index/tab_b_auto.html b/app/handle/view/index/tab_b_auto.html index 795a1a4..ee4f38c 100644 --- a/app/handle/view/index/tab_b_auto.html +++ b/app/handle/view/index/tab_b_auto.html @@ -205,6 +205,7 @@ + diff --git a/app/handle/view/index/tab_b_sb.html b/app/handle/view/index/tab_b_sb.html index bcdd41d..fe1dfe9 100644 --- a/app/handle/view/index/tab_b_sb.html +++ b/app/handle/view/index/tab_b_sb.html @@ -490,6 +490,7 @@ + diff --git a/app/handle/view/index/tab_dice.html b/app/handle/view/index/tab_dice.html index 9f3daa6..8f9f805 100644 --- a/app/handle/view/index/tab_dice.html +++ b/app/handle/view/index/tab_dice.html @@ -124,6 +124,7 @@ + diff --git a/app/handle/view/index/tab_dt.html b/app/handle/view/index/tab_dt.html index 6e24830..997ba59 100644 --- a/app/handle/view/index/tab_dt.html +++ b/app/handle/view/index/tab_dt.html @@ -233,6 +233,7 @@ + \ No newline at end of file diff --git a/app/handle/view/index/tab_dt_auto.html b/app/handle/view/index/tab_dt_auto.html index 23a6080..4bfb158 100644 --- a/app/handle/view/index/tab_dt_auto.html +++ b/app/handle/view/index/tab_dt_auto.html @@ -174,6 +174,7 @@ + diff --git a/app/handle/view/index/tab_dt_sb.html b/app/handle/view/index/tab_dt_sb.html index 1208ceb..586034b 100644 --- a/app/handle/view/index/tab_dt_sb.html +++ b/app/handle/view/index/tab_dt_sb.html @@ -459,6 +459,7 @@ + diff --git a/app/handle/view/index/tab_knn.html b/app/handle/view/index/tab_knn.html index ba0a5be..faed50a 100644 --- a/app/handle/view/index/tab_knn.html +++ b/app/handle/view/index/tab_knn.html @@ -345,6 +345,7 @@ + diff --git a/app/handle/view/index/tab_nn.html b/app/handle/view/index/tab_nn.html index cf9386b..3dee3d0 100644 --- a/app/handle/view/index/tab_nn.html +++ b/app/handle/view/index/tab_nn.html @@ -620,6 +620,7 @@ + diff --git a/app/handle/view/index/tab_nn_sb.html b/app/handle/view/index/tab_nn_sb.html index c7f8bc6..f8aa232 100644 --- a/app/handle/view/index/tab_nn_sb.html +++ b/app/handle/view/index/tab_nn_sb.html @@ -620,6 +620,7 @@ + diff --git a/app/handle/view/index/tab_roulette.html b/app/handle/view/index/tab_roulette.html index 7de7b73..ac6a417 100644 --- a/app/handle/view/index/tab_roulette.html +++ b/app/handle/view/index/tab_roulette.html @@ -126,6 +126,7 @@ + diff --git a/app/handle/view/index/tab_toning.html b/app/handle/view/index/tab_toning.html index f1bf7f9..4ddb413 100644 --- a/app/handle/view/index/tab_toning.html +++ b/app/handle/view/index/tab_toning.html @@ -136,6 +136,7 @@ + diff --git a/app/listener/WsClose.php b/app/listener/WsClose.php index df948a1..c3e826e 100644 --- a/app/listener/WsClose.php +++ b/app/listener/WsClose.php @@ -3,6 +3,7 @@ declare (strict_types = 1); namespace app\listener; +use app\utils\Logger; use freedom\utils\SocketSession; use think\swoole\WebSocket; @@ -55,6 +56,6 @@ class WsClose } $tableFd->del((string) $fd); $ws->leave(SocketSession::HOUSE_NAME); - echo $fd.":退出\n"; + Logger::info(Logger::CAT_CONNECT, 'ws_close', ['fd' => $fd, 'mode' => $mode, 'table_id' => $fdInfo['table_id'] ?? '']); } } diff --git a/app/listener/WsConnect.php b/app/listener/WsConnect.php index 0a99c19..173e292 100644 --- a/app/listener/WsConnect.php +++ b/app/listener/WsConnect.php @@ -7,6 +7,7 @@ use app\services\connect\ScanConnectService; use app\services\connect\SpaceConnectService; use app\services\connect\UserConnectService; use app\services\connect\ManagerConnectService; +use app\utils\Logger; use think\Request; class WsConnect @@ -18,6 +19,11 @@ class WsConnect */ public function handle(Request $event){ $connect = $event->get('connect'); + Logger::info(Logger::CAT_CONNECT, 'ws_connect', [ + 'mode' => $connect, + 'table_id' => $event->get('table_id'), + 'account' => $event->get('account'), + ]); switch ($connect) { case 'space': SpaceConnectService::doSpaceConnect($event); diff --git a/app/listener/space/ChangeBoot.php b/app/listener/space/ChangeBoot.php index cddd1b8..40c269e 100644 --- a/app/listener/space/ChangeBoot.php +++ b/app/listener/space/ChangeBoot.php @@ -4,6 +4,7 @@ declare (strict_types = 1); namespace app\listener\space; use app\models\process\Boot; +use app\utils\Logger; use freedom\utils\SocketSession; use think\swoole\WebSocket; @@ -22,7 +23,9 @@ class ChangeBoot $modelRes = Boot::changeBoot($tableInfo); if ($modelRes['status'] == true){ $ws->to(SocketSession::HOUSE_NAME)->emit('changeBoot',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $modelRes['data']]); + Logger::info(Logger::CAT_GAME, 'change_boot', ['table_id' => $tableInfo['id'], 'table_name' => $tableInfo['table_name']]); }else{ + Logger::warn(Logger::CAT_GAME, 'change_boot_fail', ['table_id' => $tableInfo['id'], 'msg' => $modelRes['msg']]); $ws->emit('changeBoot', ['status' => false, 'msg' => $modelRes['msg']]); } }else{ diff --git a/app/services/connect/SpaceConnectService.php b/app/services/connect/SpaceConnectService.php index dbba321..c69127a 100644 --- a/app/services/connect/SpaceConnectService.php +++ b/app/services/connect/SpaceConnectService.php @@ -6,6 +6,7 @@ namespace app\services\connect; use app\models\table\Table; use app\models\table\UserController; +use app\utils\Logger; use freedom\utils\SocketSession; use think\Request; @@ -38,8 +39,8 @@ class SpaceConnectService $username = trim($event->get('account')); $userController = UserController::get(['id' => $userId, 'username' => $username, 'login_token' => $loginToken]); if (!$tableInfo || !$userController){ + Logger::warn(Logger::CAT_CONNECT, 'space_auth_fail', ['table_id' => $tableId, 'username' => $username, 'has_table' => !!$tableInfo, 'has_user' => !!$userController]); $ws->emit('onlineLogin',['status' => false, 'msg' => 'not_table_data']); - //$ws->close(); return; } $lastNumberTab = InitTableService::initTable($tableInfo); @@ -54,7 +55,9 @@ class SpaceConnectService $round['show_card'] = GetCardService::getCard($tableInfo,$lastNumberTab); $ws->emit('onlineLogin',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); SocketSession::saveSocketSession(['table_id' => $tableInfo['id'], 'table_name' => $tableInfo['table_name']],'space'); + Logger::info(Logger::CAT_CONNECT, 'space_login_ok', ['table_id' => $tableInfo['id'], 'table_name' => $tableInfo['table_name'], 'username' => $username]); }else{ + Logger::warn(Logger::CAT_CONNECT, 'space_init_fail', ['table_id' => $tableId, 'username' => $username]); $ws->emit('onlineLogin',['status' => false, 'table_id' => $tableInfo['id'], 'msg' => 'link_server_fail']); //$ws->close(); } diff --git a/app/services/opening/OpeningBaccaratService.php b/app/services/opening/OpeningBaccaratService.php index 832fcd4..2205094 100644 --- a/app/services/opening/OpeningBaccaratService.php +++ b/app/services/opening/OpeningBaccaratService.php @@ -11,6 +11,7 @@ use app\services\waybill\WaybillRemindService; use freedom\utils\CardPosition; use freedom\utils\RedisUtil; use freedom\utils\SocketSession; +use app\utils\Logger; use think\swoole\Websocket; /** @@ -32,6 +33,7 @@ class OpeningBaccaratService //判断结果并推送结果 $res = self::doOpening($event,$tableInfo); if ($res['status'] == false){ + Logger::warn(Logger::CAT_GAME, 'opening_baccarat_fail', ['table_id' => $tableInfo['id'], 'msg' => $res['msg']]); $ws->emit('openingBaccarat',['status' => false, 'msg' => $res['msg']]); return; } @@ -52,6 +54,7 @@ class OpeningBaccaratService ); $ws->emit('openingBaccarat',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); $ws->to(SocketSession::HOUSE_NAME)->emit('openingBaccaratResult',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); + Logger::info(Logger::CAT_GAME, 'opening_baccarat', ['table_id' => $tableInfo['id'], 'opening' => $opening, 'pair' => $pair, 'luck_six' => $luck_six]); //处理注单 self::doBet($ws,$tableInfo,$lastNumberTabInfo); //处理好路 diff --git a/app/services/opening/OpeningDiceService.php b/app/services/opening/OpeningDiceService.php index bb8257a..bcc97ba 100644 --- a/app/services/opening/OpeningDiceService.php +++ b/app/services/opening/OpeningDiceService.php @@ -10,6 +10,7 @@ use app\models\user\User; use app\services\connect\InitTableService; use freedom\utils\DiceUtil; use freedom\utils\SocketSession; +use app\utils\Logger; use think\swoole\Websocket; /** @@ -31,6 +32,7 @@ class OpeningDiceService //判断结果并推送结果 $res = self::doOpening($event,$tableInfo); if ($res['status'] == false){ + Logger::warn(Logger::CAT_GAME, 'opening_dice_fail', ['table_id' => $tableInfo['id'], 'msg' => $res['msg']]); $ws->emit('openingDice',['status' => false, 'msg' => $res['msg']]); return; } @@ -47,6 +49,7 @@ class OpeningDiceService ); $ws->emit('openingDice',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); $ws->to(SocketSession::HOUSE_NAME)->emit('openingDiceResult',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); + Logger::info(Logger::CAT_GAME, 'opening_dice', ['table_id' => $tableInfo['id'], 'result' => $resultArray]); //处理注单 self::doBet($ws,$tableInfo,$lastNumberTabInfo,$resultArray,$resultParse); } diff --git a/app/services/opening/OpeningDtService.php b/app/services/opening/OpeningDtService.php index 34e932c..6c8dc18 100644 --- a/app/services/opening/OpeningDtService.php +++ b/app/services/opening/OpeningDtService.php @@ -13,6 +13,7 @@ use freedom\utils\CardPosition; use freedom\utils\RedisUtil; use freedom\utils\SocketSession; use think\facade\Env; +use app\utils\Logger; use think\swoole\Websocket; /** @@ -35,6 +36,7 @@ class OpeningDtService //判断结果并推送结果 $res = self::doOpening($event,$tableInfo); if ($res['status'] == false){ + Logger::warn(Logger::CAT_GAME, 'opening_dt_fail', ['table_id' => $tableInfo['id'], 'msg' => $res['msg']]); $ws->emit('openingDt',['status' => false, 'msg' => $res['msg']]); return; } @@ -52,6 +54,7 @@ class OpeningDtService ); $ws->emit('openingDt',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); $ws->to(SocketSession::HOUSE_NAME)->emit('openingDtResult',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); + Logger::info(Logger::CAT_GAME, 'opening_dt', ['table_id' => $tableInfo['id'], 'opening' => $opening]); //处理注单 self::doBet($ws,$tableInfo,$lastNumberTabInfo); //处理好路 diff --git a/app/services/opening/OpeningNnService.php b/app/services/opening/OpeningNnService.php index 71fdc2c..a96aa4e 100644 --- a/app/services/opening/OpeningNnService.php +++ b/app/services/opening/OpeningNnService.php @@ -11,6 +11,7 @@ use app\services\connect\InitTableService; use freedom\utils\CardPositionNn; use freedom\utils\RedisUtil; use freedom\utils\SocketSession; +use app\utils\Logger; use think\swoole\Websocket; class OpeningNnService @@ -26,6 +27,7 @@ class OpeningNnService //判断结果并推送结果 $res = self::doOpening($event,$tableInfo); if ($res['status'] == false){ + Logger::warn(Logger::CAT_GAME, 'opening_nn_fail', ['table_id' => $tableInfo['id'], 'msg' => $res['msg']]); $ws->emit('openingNn',['status' => false, 'msg' => $res['msg']]); return; } @@ -41,6 +43,7 @@ class OpeningNnService $round = array_merge($round,$data); $ws->emit('openingNn',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); $ws->to(SocketSession::HOUSE_NAME)->emit('openingNnResult',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); + Logger::info(Logger::CAT_GAME, 'opening_nn', ['table_id' => $tableInfo['id'], 'result_banker' => $data['result_banker'], 'win_p1' => $data['win_player_1'], 'win_p2' => $data['win_player_2'], 'win_p3' => $data['win_player_3']]); //处理注单 self::doBet($ws,$tableInfo,$lastNumberTabInfo,$data); } diff --git a/app/services/opening/OpeningRouletteService.php b/app/services/opening/OpeningRouletteService.php index 8096ca4..5d81602 100644 --- a/app/services/opening/OpeningRouletteService.php +++ b/app/services/opening/OpeningRouletteService.php @@ -8,6 +8,7 @@ use app\models\process\Boot; use app\models\process\NumberTab; use app\models\user\User; use app\services\connect\InitTableService; +use app\utils\Logger; use freedom\utils\RouletteUtil; use freedom\utils\SocketSession; use think\swoole\Websocket; @@ -31,6 +32,7 @@ class OpeningRouletteService //判断结果并推送结果 $res = self::doOpening($event,$tableInfo); if ($res['status'] == false){ + Logger::warn(Logger::CAT_GAME, 'opening_roulette_fail', ['table_id' => $tableInfo['id'], 'msg' => $res['msg']]); $ws->emit('openingRoulette',['status' => false,'table_id' => $tableInfo['id'], 'msg' => $res['msg']]); return; } @@ -47,6 +49,7 @@ class OpeningRouletteService ); $ws->emit('openingRoulette',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); $ws->to(SocketSession::HOUSE_NAME)->emit('openingRouletteResult',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); + Logger::info(Logger::CAT_GAME, 'opening_roulette', ['table_id' => $tableInfo['id'], 'result' => $round['result'] ?? '']); //处理注单 self::doBet($ws,$tableInfo,$lastNumberTabInfo,$result,$resultParse); } diff --git a/app/services/opening/OpeningTcService.php b/app/services/opening/OpeningTcService.php index 536b5e7..8dc2a5e 100644 --- a/app/services/opening/OpeningTcService.php +++ b/app/services/opening/OpeningTcService.php @@ -11,6 +11,7 @@ use app\services\connect\InitTableService; use freedom\utils\CardPositionTc; use freedom\utils\RedisUtil; use freedom\utils\SocketSession; +use app\utils\Logger; use think\swoole\Websocket; class OpeningTcService @@ -26,6 +27,7 @@ class OpeningTcService //判断结果并推送结果 $res = self::doOpening($event,$tableInfo); if ($res['status'] == false){ + Logger::warn(Logger::CAT_GAME, 'opening_tc_fail', ['table_id' => $tableInfo['id'], 'msg' => $res['msg']]); $ws->emit('openingTc',['status' => false, 'msg' => $res['msg']]); return; } @@ -41,6 +43,7 @@ class OpeningTcService $round = array_merge($round,$data); $ws->emit('openingTc',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); $ws->to(SocketSession::HOUSE_NAME)->emit('openingTcResult',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); + Logger::info(Logger::CAT_GAME, 'opening_tc', ['table_id' => $tableInfo['id'], 'result_banker' => $data['result_banker'], 'win_p1' => $data['win_player_1'], 'win_p2' => $data['win_player_2'], 'win_p3' => $data['win_player_3']]); //处理注单 self::doBet($ws,$tableInfo,$lastNumberTabInfo,$data); } diff --git a/app/services/opening/OpeningToningService.php b/app/services/opening/OpeningToningService.php index abc161a..56a3bd6 100644 --- a/app/services/opening/OpeningToningService.php +++ b/app/services/opening/OpeningToningService.php @@ -10,6 +10,7 @@ use app\models\user\User; use app\services\connect\InitTableService; use freedom\utils\SocketSession; use freedom\utils\ToningUtil; +use app\utils\Logger; use think\swoole\Websocket; /** @@ -31,6 +32,7 @@ class OpeningToningService //判断结果并推送结果 $res = self::doOpening($event,$tableInfo); if ($res['status'] == false){ + Logger::warn(Logger::CAT_GAME, 'opening_toning_fail', ['table_id' => $tableInfo['id'], 'msg' => $res['msg']]); $ws->emit('openingToning',['status' => false, 'msg' => $res['msg']]); return; } @@ -46,6 +48,7 @@ class OpeningToningService ); $ws->emit('openingToning',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); $ws->to(SocketSession::HOUSE_NAME)->emit('openingToningResult',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]); + Logger::info(Logger::CAT_GAME, 'opening_toning', ['table_id' => $tableInfo['id'], 'result' => $result]); //处理注单 self::doBet($ws,$tableInfo,$lastNumberTabInfo); } diff --git a/app/services/process/EndBetService.php b/app/services/process/EndBetService.php index 68a9aa3..e78c55d 100644 --- a/app/services/process/EndBetService.php +++ b/app/services/process/EndBetService.php @@ -6,6 +6,7 @@ namespace app\services\process; use app\models\process\NumberTab; use app\services\connect\InitTableService; +use app\utils\Logger; use freedom\utils\RedisUtil; use freedom\utils\SocketSession; @@ -41,7 +42,9 @@ class EndBetService 'number_tab_status' => InitTableService::numberTabStatus($numberTabInfo) ] ]); + Logger::info(Logger::CAT_GAME, 'end_bet', ['table_id' => $tableInfo['id'], 'nt_id' => $numberTabId]); }else{ + Logger::warn(Logger::CAT_GAME, 'end_bet_fail', ['table_id' => $tableInfo['id'], 'msg' => $modelRes['msg']]); $ws->emit('endBet', ['status' => false, 'msg' => $modelRes['msg']]); } } diff --git a/app/services/process/StartBetService.php b/app/services/process/StartBetService.php index 6d8ac17..846735c 100644 --- a/app/services/process/StartBetService.php +++ b/app/services/process/StartBetService.php @@ -6,6 +6,7 @@ namespace app\services\process; use app\models\process\NumberTab; use app\services\connect\InitTableService; +use app\utils\Logger; use freedom\utils\SocketSession; /** @@ -44,7 +45,9 @@ class StartBetService $ws->emit('startBet', $responseData); //启动倒计时(该处以后会废弃掉) CountdownService::countdown($numberTabId,$tableInfo,$modelRes['data']); + Logger::info(Logger::CAT_GAME, 'start_bet', ['table_id' => $tableInfo['id'], 'table_name' => $tableInfo['table_name'], 'nt_id' => $numberTabId]); }else{ + Logger::warn(Logger::CAT_GAME, 'start_bet_fail', ['table_id' => $tableInfo['id'], 'msg' => $modelRes['msg']]); $ws->emit('startBet', ['status' => false, 'msg' => $modelRes['msg']]); } } diff --git a/app/utils/Logger.php b/app/utils/Logger.php new file mode 100644 index 0000000..7275564 --- /dev/null +++ b/app/utils/Logger.php @@ -0,0 +1,40 @@ + false, // 独立日志级别 - 'apart_level' => [], + 'apart_level' => ['error', 'sql'], // 最大日志文件数量 - 'max_files' => 0, + 'max_files' => 30, // 使用JSON格式记录 'json' => false, // 日志处理 @@ -37,7 +37,7 @@ return [ // 日志输出格式化 'format' => '[%s][%s] %s', // 是否实时写入 - 'realtime_write' => false, + 'realtime_write' => true, ], // 其它日志通道配置 ], diff --git a/public/static/handle/js/error-report.js b/public/static/handle/js/error-report.js new file mode 100644 index 0000000..0a3998b --- /dev/null +++ b/public/static/handle/js/error-report.js @@ -0,0 +1,47 @@ +(function() { + var reportUrl = '/log/report'; + var queue = []; + var sending = false; + + function send(data) { + if (queue.length >= 10) return; + data.source = 'handle'; + data.time = new Date().toISOString(); + data.url = location.href; + queue.push(data); + flush(); + } + + function flush() { + if (sending || queue.length === 0) return; + sending = true; + var item = queue.shift(); + var xhr = new XMLHttpRequest(); + xhr.open('POST', reportUrl); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.onloadend = function() { sending = false; flush(); }; + xhr.onerror = function() { sending = false; }; + xhr.timeout = 3000; + xhr.send(JSON.stringify(item)); + } + + window.onerror = function(message, source, lineno, colno, error) { + send({ + type: 'error', + message: String(message), + stack: error && error.stack ? error.stack.substring(0, 2000) : '', + file: source, + line: lineno, + col: colno + }); + }; + + window.addEventListener('unhandledrejection', function(event) { + var reason = event.reason; + send({ + type: 'unhandledrejection', + message: reason && reason.message ? reason.message : String(reason), + stack: reason && reason.stack ? reason.stack.substring(0, 2000) : '' + }); + }); +})(); diff --git a/route/app.php b/route/app.php index d8e09e3..abc8a26 100644 --- a/route/app.php +++ b/route/app.php @@ -15,3 +15,19 @@ Route::get('think', function () { }); Route::get('hello/:name', 'index/hello'); + +Route::post('log/report', function () { + $data = request()->post(); + \app\utils\Logger::error(\app\utils\Logger::CAT_FRONTEND, $data['message'] ?? 'unknown', [ + 'source' => $data['source'] ?? 'unknown', + 'type' => $data['type'] ?? 'error', + 'stack' => isset($data['stack']) ? substr($data['stack'], 0, 2000) : '', + 'file' => $data['file'] ?? '', + 'url' => $data['url'] ?? '', + 'line' => $data['line'] ?? '', + 'col' => $data['col'] ?? '', + 'ua' => request()->header('user-agent', ''), + 'ip' => request()->ip(), + ]); + return json(['status' => 1]); +});