service = $service; $this->quota = $quota; $this->alertType = $alertType; $this->currentUsage = $currentUsage; $this->quotaLimit = $quotaLimit; $this->usagePercentage = $usagePercentage; $this->alertThreshold = $alertThreshold; $this->alertTime = now(); $this->metadata = $metadata; } /** * 获取事件数据数组 * * @return array */ public function toArray(): array { return [ 'service_id' => $this->service->id, 'service_code' => $this->service->code, 'service_name' => $this->service->name, 'quota_id' => $this->quota->id, 'quota_type' => $this->quota->quota_type, 'quota_type_label' => QUOTA_TYPE::from($this->quota->quota_type)->getLabel(), 'alert_type' => $this->alertType, 'current_usage' => $this->currentUsage, 'quota_limit' => $this->quotaLimit, 'usage_percentage' => $this->usagePercentage, 'alert_threshold' => $this->alertThreshold, 'alert_time' => $this->alertTime->toISOString(), 'metadata' => $this->metadata, ]; } /** * 获取告警级别 * * @return string */ public function getAlertLevel(): string { return match ($this->alertType) { self::ALERT_TYPE_WARNING => 'WARNING', self::ALERT_TYPE_CRITICAL => 'CRITICAL', self::ALERT_TYPE_EXHAUSTED => 'CRITICAL', default => 'INFO', }; } /** * 获取告警消息 * * @return string */ public function getAlertMessage(): string { $serviceName = $this->service->name; $quotaTypeLabel = QUOTA_TYPE::from($this->quota->quota_type)->getLabel(); $percentage = number_format($this->usagePercentage, 1); return match ($this->alertType) { self::ALERT_TYPE_WARNING => "第三方服务 [{$serviceName}] 的 {$quotaTypeLabel} 配额使用率已达到 {$percentage}%,请注意监控", self::ALERT_TYPE_CRITICAL => "第三方服务 [{$serviceName}] 的 {$quotaTypeLabel} 配额使用率已达到 {$percentage}%,即将耗尽", self::ALERT_TYPE_EXHAUSTED => "第三方服务 [{$serviceName}] 的 {$quotaTypeLabel} 配额已耗尽,服务调用将被限制", default => "第三方服务 [{$serviceName}] 配额状态更新", }; } /** * 获取剩余配额 * * @return int */ public function getRemainingQuota(): int { return max(0, $this->quotaLimit - $this->currentUsage); } /** * 判断是否为严重告警 * * @return bool */ public function isCritical(): bool { return in_array($this->alertType, [self::ALERT_TYPE_CRITICAL, self::ALERT_TYPE_EXHAUSTED]); } /** * 获取预计耗尽时间 * * @return \Carbon\Carbon|null */ public function getEstimatedExhaustionTime(): ?\Carbon\Carbon { if ($this->alertType === self::ALERT_TYPE_EXHAUSTED) { return null; // 已经耗尽 } // 基于当前使用率估算耗尽时间 $quotaType = QUOTA_TYPE::from($this->quota->quota_type); $windowStart = \Carbon\Carbon::instance($quotaType->getCurrentWindowStart()); $windowEnd = \Carbon\Carbon::instance($quotaType->getCurrentWindowEnd()); $elapsedTime = now()->diffInMinutes($windowStart); if ($elapsedTime <= 0 || $this->currentUsage <= 0) { return null; } $usageRate = $this->currentUsage / $elapsedTime; // 每分钟使用量 $remainingQuota = $this->getRemainingQuota(); if ($usageRate <= 0) { return null; } $minutesToExhaustion = $remainingQuota / $usageRate; return now()->addMinutes($minutesToExhaustion); } /** * 获取建议操作 * * @return array */ public function getSuggestedActions(): array { $actions = []; switch ($this->alertType) { case self::ALERT_TYPE_WARNING: $actions[] = '监控配额使用情况'; $actions[] = '检查是否有异常调用'; $actions[] = '考虑优化调用频率'; break; case self::ALERT_TYPE_CRITICAL: $actions[] = '立即检查调用情况'; $actions[] = '暂停非必要的API调用'; $actions[] = '联系服务提供商增加配额'; $actions[] = '启用备用服务(如有)'; break; case self::ALERT_TYPE_EXHAUSTED: $actions[] = '停止所有API调用'; $actions[] = '等待配额重置'; $actions[] = '切换到备用服务'; $actions[] = '联系服务提供商紧急增加配额'; break; } return $actions; } }