Reduce metrics overhead and cache sysstat days

This commit is contained in:
root
2026-01-31 17:29:06 +02:00
parent 6fb4b6beef
commit 748d6c56f8
2 changed files with 50 additions and 8 deletions

View File

@@ -8,6 +8,8 @@ use Illuminate\Database\Eloquent\Model;
class ServerProcess extends Model class ServerProcess extends Model
{ {
protected static ?string $latestBatchIdCache = null;
protected $fillable = [ protected $fillable = [
'batch_id', 'batch_id',
'rank', 'rank',
@@ -27,9 +29,11 @@ class ServerProcess extends Model
public function scopeLatestBatch($query) public function scopeLatestBatch($query)
{ {
$latestBatchId = static::orderBy('captured_at', 'desc')->value('batch_id'); if (static::$latestBatchIdCache === null) {
static::$latestBatchIdCache = static::orderBy('captured_at', 'desc')->value('batch_id');
}
return $query->where('batch_id', $latestBatchId); return $query->where('batch_id', static::$latestBatchIdCache);
} }
public static function captureProcesses(array $processes, int $total = 0): string public static function captureProcesses(array $processes, int $total = 0): string
@@ -44,11 +48,16 @@ class ServerProcess extends Model
->limit(10) ->limit(10)
->pluck('batch_id'); ->pluck('batch_id');
static::whereNotIn('batch_id', $keepBatches)->delete(); if ($keepBatches->isNotEmpty()) {
static::whereNotIn('batch_id', $keepBatches)->delete();
}
static::$latestBatchIdCache = $batchId;
// Insert new processes // Insert new processes
$rows = [];
foreach ($processes as $index => $proc) { foreach ($processes as $index => $proc) {
static::create([ $rows[] = [
'batch_id' => $batchId, 'batch_id' => $batchId,
'rank' => $index + 1, 'rank' => $index + 1,
'pid' => $proc['pid'] ?? 0, 'pid' => $proc['pid'] ?? 0,
@@ -57,7 +66,11 @@ class ServerProcess extends Model
'cpu' => $proc['cpu'] ?? 0, 'cpu' => $proc['cpu'] ?? 0,
'memory' => $proc['memory'] ?? 0, 'memory' => $proc['memory'] ?? 0,
'captured_at' => $now, 'captured_at' => $now,
]); ];
}
if ($rows) {
static::insert($rows);
} }
return $batchId; return $batchId;

View File

@@ -95,6 +95,9 @@ class SysstatMetrics
$samples = []; $samples = [];
$current = $start->startOfDay(); $current = $start->startOfDay();
$lastDay = $end->startOfDay(); $lastDay = $end->startOfDay();
$startTimestamp = $start->getTimestamp();
$endTimestamp = $end->getTimestamp();
$useDailyCache = ($endTimestamp - $startTimestamp) > 21600;
while ($current <= $lastDay) { while ($current <= $lastDay) {
$fileLong = sprintf('/var/log/sysstat/sa%s', $current->format('Ymd')); $fileLong = sprintf('/var/log/sysstat/sa%s', $current->format('Ymd'));
@@ -106,15 +109,22 @@ class SysstatMetrics
continue; continue;
} }
$dayStart = $current->isSameDay($start) ? $start : $current->startOfDay(); if ($useDailyCache) {
$dayEnd = $current->isSameDay($end) ? $end : $current->endOfDay(); $statistics = $this->readSadfDay($file, $current, $options);
$statistics = $this->readSadf($file, $dayStart, $dayEnd, $options); } else {
$dayStart = $current->isSameDay($start) ? $start : $current->startOfDay();
$dayEnd = $current->isSameDay($end) ? $end : $current->endOfDay();
$statistics = $this->readSadf($file, $dayStart, $dayEnd, $options);
}
foreach ($statistics as $stat) { foreach ($statistics as $stat) {
$parsed = $this->parseSample($stat); $parsed = $this->parseSample($stat);
if ($parsed === null) { if ($parsed === null) {
continue; continue;
} }
if ($parsed['timestamp'] < $startTimestamp || $parsed['timestamp'] > $endTimestamp) {
continue;
}
$samples[] = $parsed; $samples[] = $parsed;
} }
@@ -148,6 +158,8 @@ class SysstatMetrics
], ],
); );
$process = new Process($args); $process = new Process($args);
$process->setTimeout(8);
$process->setIdleTimeout(5);
$process->run(); $process->run();
if (! $process->isSuccessful()) { if (! $process->isSuccessful()) {
@@ -167,6 +179,23 @@ class SysstatMetrics
return $stats; return $stats;
} }
/**
* @return array<int, array<string, mixed>>
*/
private function readSadfDay(string $file, CarbonImmutable $day, array $options): array
{
$mtime = @filemtime($file) ?: 0;
$optionsKey = implode(',', $options);
$cacheKey = sprintf('sysstat.sadf.day.%s.%d.%s', md5($file), $mtime, md5($optionsKey));
return Cache::remember($cacheKey, now()->addMinutes(10), function () use ($file, $day, $options): array {
$dayStart = $day->startOfDay();
$dayEnd = $day->endOfDay();
return $this->readSadf($file, $dayStart, $dayEnd, $options);
});
}
/** /**
* @return array<int, string> * @return array<int, string>
*/ */