where('service_id', $filters['service_id']); } if (isset($filters['credential_id'])) { $query->where('credential_id', $filters['credential_id']); } if (isset($filters['level'])) { $query->where('level', $filters['level']); } if (isset($filters['method'])) { $query->where('method', $filters['method']); } if (isset($filters['status_code'])) { $query->where('response_status', $filters['status_code']); } if (isset($filters['start_date'])) { $query->where('created_at', '>=', $filters['start_date']); } if (isset($filters['end_date'])) { $query->where('created_at', '<=', $filters['end_date']); } if (isset($filters['search'])) { $search = $filters['search']; $query->where(function ($q) use ($search) { $q->where('url', 'like', "%{$search}%") ->orWhere('request_id', 'like', "%{$search}%") ->orWhere('error_message', 'like', "%{$search}%"); }); } // 只查询错误日志 if (isset($filters['errors_only']) && $filters['errors_only']) { $query->errors(); } // 应用排序 $sortBy = $options['sort_by'] ?? 'created_at'; $sortOrder = $options['sort_order'] ?? 'desc'; $query->orderBy($sortBy, $sortOrder); // 应用限制 if (isset($options['limit'])) { $query->limit($options['limit']); } return $query->get(); } /** * 获取日志详情 * * @param int $logId * @return ThirdPartyLog */ public static function getById(int $logId): ThirdPartyLog { return ThirdPartyLog::with('service', 'credential')->findOrFail($logId); } /** * 获取日志统计信息 * * @param array $filters * @return array */ public static function getStats(array $filters = []): array { $query = ThirdPartyLog::query(); // 应用过滤条件 if (isset($filters['service_id'])) { $query->where('service_id', $filters['service_id']); } if (isset($filters['start_date'])) { $query->where('created_at', '>=', $filters['start_date']); } if (isset($filters['end_date'])) { $query->where('created_at', '<=', $filters['end_date']); } $total = $query->count(); $successful = $query->whereBetween('response_status', [200, 299])->count(); $errors = $query->where('response_status', '>=', 400)->count(); // 按级别统计 $levelStats = $query->selectRaw('level, COUNT(*) as count') ->groupBy('level') ->pluck('count', 'level') ->toArray(); // 按状态码统计 $statusStats = $query->selectRaw('response_status, COUNT(*) as count') ->whereNotNull('response_status') ->groupBy('response_status') ->pluck('count', 'response_status') ->toArray(); // 平均响应时间 $avgResponseTime = $query->whereNotNull('response_time') ->avg('response_time'); return [ 'total' => $total, 'successful' => $successful, 'errors' => $errors, 'success_rate' => $total > 0 ? round(($successful / $total) * 100, 2) : 0, 'avg_response_time' => $avgResponseTime ? round($avgResponseTime, 2) : null, 'by_level' => $levelStats, 'by_status' => $statusStats, ]; } /** * 获取错误日志 * * @param array $filters * @param int $limit * @return Collection */ public static function getErrorLogs(array $filters = [], int $limit = 100): Collection { $filters['errors_only'] = true; $options = ['limit' => $limit]; return static::getList($filters, $options); } /** * 获取慢请求日志 * * @param int $threshold 响应时间阈值(毫秒) * @param array $filters * @param int $limit * @return Collection */ public static function getSlowLogs(int $threshold = 5000, array $filters = [], int $limit = 100): Collection { $query = ThirdPartyLog::with('service', 'credential') ->where('response_time', '>', $threshold); // 应用其他过滤条件 if (isset($filters['service_id'])) { $query->where('service_id', $filters['service_id']); } if (isset($filters['start_date'])) { $query->where('created_at', '>=', $filters['start_date']); } if (isset($filters['end_date'])) { $query->where('created_at', '<=', $filters['end_date']); } return $query->orderBy('response_time', 'desc') ->limit($limit) ->get(); } /** * 清理旧日志 * * @param int $days 保留天数 * @return int 删除数量 */ public static function cleanup(int $days = 30): int { return ThirdPartyLog::where('created_at', '<', now()->subDays($days))->delete(); } /** * 导出日志 * * @param array $filters * @param string $format * @return array */ public static function export(array $filters = [], string $format = 'array'): array { $logs = static::getList($filters); $exported = []; foreach ($logs as $log) { $exported[] = [ 'id' => $log->id, 'service_name' => $log->service->name, 'service_code' => $log->service->code, 'request_id' => $log->request_id, 'method' => $log->method, 'url' => $log->url, 'response_status' => $log->response_status, 'response_time' => $log->response_time, 'level' => $log->level, 'error_message' => $log->error_message, 'user_id' => $log->user_id, 'ip_address' => $log->ip_address, 'created_at' => $log->created_at->toDateTimeString(), ]; } return $exported; } /** * 获取请求追踪信息 * * @param string $requestId * @return ThirdPartyLog|null */ public static function getByRequestId(string $requestId): ?ThirdPartyLog { return ThirdPartyLog::with('service', 'credential') ->where('request_id', $requestId) ->first(); } /** * 获取用户的调用日志 * * @param int $userId * @param array $options * @return Collection */ public static function getUserLogs(int $userId, array $options = []): Collection { $query = ThirdPartyLog::with('service', 'credential') ->where('user_id', $userId); $limit = $options['limit'] ?? 50; $query->limit($limit); return $query->orderBy('created_at', 'desc')->get(); } /** * 记录API调用 * * @param array $data * @return ThirdPartyLog */ public static function logApiCall(array $data): ThirdPartyLog { // 过滤敏感信息 if (isset($data['headers'])) { $data['headers'] = static::filterSensitiveData($data['headers']); } if (isset($data['params'])) { $data['params'] = static::filterSensitiveData($data['params']); } return static::create($data); } /** * 过滤敏感数据 * * @param array $data * @return array */ protected static function filterSensitiveData(array $data): array { $sensitiveFields = config('thirdparty.logging.sensitive_fields', []); foreach ($sensitiveFields as $field) { if (isset($data[$field])) { $data[$field] = '***'; } } return $data; } }