57 lines
2.0 KiB
PHP
57 lines
2.0 KiB
PHP
<?php
|
||
|
||
namespace App\Console\Commands;
|
||
|
||
use Illuminate\Console\Command;
|
||
use Illuminate\Support\Facades\Cache;
|
||
use App\Models\Setting;
|
||
|
||
class SpamAvCollectCommand extends Command
|
||
{
|
||
protected $signature = 'spamav:collect';
|
||
protected $description = 'Collect Rspamd/ClamAV metrics and persist to Settings (DB→Redis)';
|
||
|
||
public function handle(): int
|
||
{
|
||
$this->info('Collecting Spam/AV metrics…');
|
||
|
||
// Rspamd counters (kein Root nötig)
|
||
$out = trim(@shell_exec('rspamc counters 2>/dev/null') ?? '');
|
||
$ham = preg_match('/\bham\s*:\s*(\d+)/i', $out, $m1) ? (int)$m1[1] : 0;
|
||
$spam = preg_match('/\bspam\s*:\s*(\d+)/i', $out, $m2) ? (int)$m2[1] : 0;
|
||
$reject = preg_match('/\breject\s*:\s*(\d+)/i', $out, $m3) ? (int)$m3[1] : 0;
|
||
|
||
// ClamAV Version + Signatur-Datum robust ohne Datei-Zugriff
|
||
$clamLine = trim((string) @shell_exec('clamd --version 2>/dev/null || clamscan --version 2>/dev/null'));
|
||
$clamVer = $clamLine !== '' ? $clamLine : '–';
|
||
|
||
// Aus clamd/clamscan-Output das Datum am Ende herausziehen (Format: ".../Sun Oct 26 09:42:43 2025")
|
||
$sigUpdated = null;
|
||
if ($clamLine && preg_match('#/([^/]+\d{4})$#', $clamLine, $m)) {
|
||
// $m[1] ist z.B. "Sun Oct 26 09:42:43 2025"
|
||
$sigUpdated = $m[1];
|
||
}
|
||
|
||
$data = [
|
||
'ts' => time(),
|
||
'ham' => $ham,
|
||
'spam' => $spam,
|
||
'reject' => $reject,
|
||
'rspamdVer' => trim((string) @shell_exec('rspamadm version 2>/dev/null')) ?: '–',
|
||
'clamVer' => $clamVer,
|
||
'sigUpdated' => $sigUpdated,
|
||
];
|
||
|
||
// Persistieren (DB→Redis) + kurzer UI-Cache
|
||
Setting::set('spamav.metrics', $data);
|
||
Cache::put('dash.spamav', $data, 60);
|
||
|
||
$this->info(sprintf(
|
||
'ham=%d spam=%d reject=%d | rspamd=%s | clam=%s',
|
||
$data['ham'], $data['spam'], $data['reject'], $data['rspamdVer'], $data['clamVer']
|
||
));
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
}
|