contextId = unique_str(); /* * 数据已加密, 需要先做解密传递处理 */ if ($request->header('x-encrypted') == 'true') { $encryptedData = $request->param('encryptedData',''); if($encryptedData) { try{ $jsonInput = \app\Request::decryptCryptoJSData($encryptedData); }catch (\Throwable){ $jsonInput = null; } if($jsonInput) { return json(['code'=>500,'message'=>'E0.数据解密失败']); } $request->withInput($jsonInput); } } /** * @var Response $response */ $response = $next($request); $response->header([ 'R-Context-Id' => $request->contextId, ]); return $response; } protected $noHttpLog = [ 'GET@/adminapi/system/request-record' ]; /** * 结束 * @param Response $response * @return void */ public function end(Response $response): void { $request = $this->app->request; $log = (array)$this->app->config->get('admin.httpLog'); $logOpen = $log['open'] ?? false; if (!$logOpen || in_array($request->method() . '@' . $request->pathinfo(),$this->noHttpLog)) { return; } $request_start_time = $request->time(true); $request_end_time = microtime(true); $running_time = ($request_end_time - $request_start_time) * 1000; $openRecordStartTime = $log['open_start_time'] ?? 0; $openRecordEndTime = $log['open_end_time'] ?? 0; if ($openRecordStartTime && $openRecordEndTime) { if ($request_end_time < $openRecordStartTime || $openRecordEndTime < $request_end_time) { return; } } $rules = array_merge([ 'include_methods' => [], 'include_responses' => [], 'include_codes' => [], 'exclude_codes' => [], ], $log['recordRules'] ?? []); // 请求类型(GET/POST/PUT/DELETE) $request_method = $request->method(); if (!in_array($request_method, $rules['include_methods'])) { return; } // 返回类型(JSON/HTML/XML) $response_type = get_class($response); if (!in_array($response_type, $rules['include_responses'])) { return; } // 返回状态码(Http Status Code) $response_code = $response->getCode(); if (in_array($response_type, $rules['exclude_codes'])) { return; } if (count($rules['include_codes']) > 0) { if (!in_array($response_type, $rules['include_codes'])) { return; } } $request_start_time = explode('.', $request_start_time); $request_end_time = explode('.', $request_end_time); $request_date = date('Y-m-d H:i:s', $request_start_time[0]); $response_data = $response->getContent(); // 限制response_data记录长度 $response_max = $log['response_max'] ?? 0; if ($response_max) { $response_data = mb_substr($response_data, 0, $response_max, 'utf-8'); } $request_body = $request->param(); try { // 对文件类型的数据做处理 $request_file = $request->file(); if ($request_file && count($request_file) > 0) { /** * @var UploadedFile $file */ foreach ($request->file() as $key => $file) { $request_body[$key] = [ 'md5' => $file->md5(), 'name' => $file->getOriginalName(), 'size' => $file->getSize(), ]; } } $route = $request->rule()->getRoute(); $client = \app\Request::getClient(); (new SysRequestRecord)->save([ 'context_id' => $request->contextId, 'client_id' => $client->id, 'client_name' => $client->name, 'client_version' => $client->version, 'request_date' => $request_date, 'request_time' => $request_date . '.' . ($request_start_time[1] ?? 0), 'request_method' => $request_method, 'request_end_time' => date('Y-m-d H:i:s', $request_end_time[0]) . '.' . ($request_end_time[1] ?? 0), 'request_headers' => json_encode($request->header(), JSON_UNESCAPED_UNICODE), 'request_body' => json_encode($request_body, JSON_UNESCAPED_UNICODE), 'request_path' => $request->url(), 'request_domain' => $request->domain(), 'response_type' => $response_type, 'response_code' => $response_code, 'response_data' => $response_data, 'running_time' => (int)$running_time, 'running_memory_limit' => ini_get('memory_limit'), 'running_memory_usage' => memory_get_peak_usage(), 'request_ip' => $request->ip(), 'rule_name' => $request->rule()->getName(), 'rule_route' => is_array($route) ? implode('@', $route) : @json_encode($route), ]); } catch (\Throwable $e) { $this->app->log->error("[ContextMiddleware::end] 日志写入失败->{$e->getMessage()}"); } } }