logRequestStart($joinPoint, $traceId); try { // 执行目标方法 $result = $joinPoint->proceed(); // 记录请求成功 $this->logRequestSuccess($joinPoint, $result, $startTime, $traceId); return $result; } catch (\Exception $e) { // 记录请求异常 $this->logRequestException($joinPoint, $e, $startTime, $traceId); throw $e; } } /** * 记录请求开始 */ private function logRequestStart(JoinPoint $joinPoint, string $traceId): void { $request = $this->getRequest(); $method = $joinPoint->getMethod(); $class = $joinPoint->getTarget()::class; $logData = [ 'trace_id' => $traceId, 'event' => 'request_start', 'class' => $class, 'method' => $method, 'request_uri' => $request->uri(), 'request_method' => $request->method(), 'client_ip' => $request->getClientIp(), 'user_agent' => $request->userAgent(), 'timestamp' => date('Y-m-d H:i:s'), ]; // 记录请求参数(排除敏感信息) $params = $this->filterSensitiveData($request->all()); if (!empty($params)) { $logData['request_params'] = $params; } $this->writeLog('INFO', 'Request started', $logData); } /** * 记录请求成功 */ private function logRequestSuccess(JoinPoint $joinPoint, mixed $result, float $startTime, string $traceId): void { $executionTime = round((microtime(true) - $startTime) * 1000, 2); $method = $joinPoint->getMethod(); $class = $joinPoint->getTarget()::class; $logData = [ 'trace_id' => $traceId, 'event' => 'request_success', 'class' => $class, 'method' => $method, 'execution_time' => $executionTime, 'memory_usage' => memory_get_usage(true), 'memory_peak' => memory_get_peak_usage(true), 'timestamp' => date('Y-m-d H:i:s'), ]; // 记录响应数据(排除敏感信息) if ($result !== null && !is_resource($result)) { $responseData = $this->filterSensitiveData($result); if (is_array($responseData) && count($responseData) > 100) { $logData['response_size'] = count($responseData); $logData['response_type'] = gettype($result); } else { $logData['response_data'] = $responseData; } } // 性能警告 if ($executionTime > 1000) { $logData['performance_warning'] = 'Slow request detected'; $this->writeLog('WARNING', 'Slow request completed', $logData); } else { $this->writeLog('INFO', 'Request completed successfully', $logData); } } /** * 记录请求异常 */ private function logRequestException(JoinPoint $joinPoint, \Exception $e, float $startTime, string $traceId): void { $executionTime = round((microtime(true) - $startTime) * 1000, 2); $method = $joinPoint->getMethod(); $class = $joinPoint->getTarget()::class; $logData = [ 'trace_id' => $traceId, 'event' => 'request_exception', 'class' => $class, 'method' => $method, 'execution_time' => $executionTime, 'exception_type' => get_class($e), 'exception_code' => $e->getCode(), 'exception_message' => $e->getMessage(), 'exception_file' => $e->getFile(), 'exception_line' => $e->getLine(), 'stack_trace' => $e->getTraceAsString(), 'timestamp' => date('Y-m-d H:i:s'), ]; $this->writeLog('ERROR', 'Request failed with exception', $logData); } /** * 获取当前请求对象 */ private function getRequest(): \Fendx\Web\Request\Request { return \Fendx\Web\Request\Request::createFromGlobals(); } /** * 过滤敏感数据 */ private function filterSensitiveData(mixed $data): mixed { if (!is_array($data)) { return $data; } $sensitiveFields = [ 'password', 'passwd', 'secret', 'token', 'key', 'credit_card', 'bank_account', 'ssn', 'id_card' ]; $filtered = []; foreach ($data as $key => $value) { if (in_array(strtolower($key), $sensitiveFields)) { $filtered[$key] = '***'; } elseif (is_array($value)) { $filtered[$key] = $this->filterSensitiveData($value); } else { $filtered[$key] = $value; } } return $filtered; } /** * 写入日志 */ private function writeLog(string $level, string $message, array $data): void { $logEntry = [ 'level' => $level, 'message' => $message, 'data' => $data, ]; // 这里应该调用实际的日志系统 // Log::write($level, $message, $data); // 临时实现:写入文件 $logFile = runtime_path('logs/app_' . date('Y-m-d') . '.log'); $logLine = date('Y-m-d H:i:s') . " [{$level}] {$message} " . json_encode($logEntry, JSON_UNESCAPED_UNICODE) . PHP_EOL; $logDir = dirname($logFile); if (!is_dir($logDir)) { mkdir($logDir, 0755, true); } file_put_contents($logFile, $logLine, FILE_APPEND | LOCK_EX); } }