74 lines
2.3 KiB
PHP
74 lines
2.3 KiB
PHP
|
|
<?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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|