Files
ai-web/app/Services/Crawler/CrawlAlertService.php

74 lines
2.3 KiB
PHP
Raw Normal View History

2026-02-18 12:56:36 +08:00
<?php
declare(strict_types=1);
namespace App\Services\Crawler;
use App\Enums\CrawlAlertSeverity;
use App\Models\CrawlAlert;
use App\Models\CrawlRule;
use App\Models\CrawlRun;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class CrawlAlertService
{
public function notify(
CrawlAlertSeverity $severity,
string $type,
string $message,
?CrawlRule $rule = null,
?CrawlRun $run = null,
?array $context = null,
): CrawlAlert {
$alert = CrawlAlert::query()->create([
'run_id' => $run?->id,
'rule_id' => $rule?->id,
'severity' => $severity,
'type' => $type,
'message' => $message,
'context' => $context,
'is_resolved' => false,
]);
$recipient = $rule?->alert_email ?: config('crawler.default_alert_email');
if (is_string($recipient) && $recipient !== '') {
try {
Mail::raw($this->buildEmailBody($alert), static function ($mail) use ($recipient, $severity): void {
$mail->to($recipient)
->subject(sprintf('[Crawler][%s] 采集告警', strtoupper($severity->value)));
});
} catch (\Throwable $exception) {
Log::warning('Crawler alert email failed', [
'alert_id' => $alert->id,
'error' => $exception->getMessage(),
]);
}
}
return $alert;
}
private function buildEmailBody(CrawlAlert $alert): string
{
$lines = [
'采集告警通知',
sprintf('等级: %s', $alert->severity?->value ?? 'unknown'),
sprintf('类型: %s', $alert->type),
sprintf('信息: %s', $alert->message),
sprintf('规则ID: %s', (string) ($alert->rule_id ?? '-')),
sprintf('运行ID: %s', (string) ($alert->run_id ?? '-')),
sprintf('时间: %s', (string) $alert->created_at),
];
if (is_array($alert->context) && $alert->context !== []) {
$lines[] = '上下文:';
$lines[] = json_encode($alert->context, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) ?: '{}';
}
return implode("\n", $lines);
}
}