getStatusCode(); return $response; } catch (\Throwable $e) { $httpCode = $e->getCode() ?: 500; $message = mb_substr($e->getMessage(), 0, 180); $status = 0; throw $e; } finally { $latency = (int)((microtime(true) - $start) * 1000); $this->enqueue($request, $httpCode, $status, $message, $latency); } } protected function enqueue(Request $req, int $httpCode, int $status, ?string $message, int $latencyMs): void { $buf = AuditBuffer::instance(); $user = $this->currentUser($req->user); $paramsBrief = $this->briefParams($req->all()); $ua = (string)($req->header('user-agent') ?? ''); if (mb_strlen($ua) > 191) $ua = mb_substr($ua, 0, 191); $payload = [ 'user_id' => $user['id'] ?? null, 'user_name' => $user['name'] ?? null, 'route' => $req->path(), 'method' => $req->method(), 'ip' => $req->getRealIp(), 'ua' => $ua, 'action' => $buf->action ?? $req->action, 'status' => $status, 'http_code' => $httpCode, 'latency_ms' => $latencyMs, 'params_brief' => $paramsBrief, // 数组,消费者再编码 'changes' => $buf->changes, // 数组,消费者再编码 'message' => $message, 'ts' => time() ]; try { Queue::send('audit_log', $payload); // 异步 } catch (\Throwable $e) { // 遵循“绝不回落同步写”,仅记录错误 Log::error('audit enqueue failed: '.$e->getMessage()); } } protected function briefParams(array $params): array { // $mask = ['password','pwd','token','secret','access_token','refresh_token','file','content','html']; $mask = []; $out = []; foreach ($params as $k=>$v) { if (in_array($k, $mask, true)) { $out[$k] = '***'; continue; } if (is_array($v)) { $out[$k] = '[array('.count($v).')]'; continue; } $s = (string)$v; $out[$k] = mb_strlen($s) > 120 ? mb_substr($s, 0, 120).'…' : $s; } return $out; } protected function inferAction(Request $req): ?string { $m = strtoupper($req->method()); if ($m === 'POST') return 'create'; if ($m === 'PUT' || $m === 'PATCH') return 'update'; if ($m === 'DELETE') return 'delete'; return 'view'; } protected function currentUser($user): array { $user = (array)$user; if (!$user) { return [ 'id' => 0, 'name' => 'guest' ]; } else { if (!isset($user['uname'])) { $user['uname'] = User::where('id', $user['id'])->value('name'); } } return [ 'id' => $user['uid'] ?? 0, 'name' => $user['uname'] ?? 'guest' ]; } }