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
{
protected static ?string $latestBatchIdCache = null;
protected $fillable = [
'batch_id',
'rank',
@@ -27,9 +29,11 @@ class ServerProcess extends Model
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
@@ -44,11 +48,16 @@ class ServerProcess extends Model
->limit(10)
->pluck('batch_id');
static::whereNotIn('batch_id', $keepBatches)->delete();
if ($keepBatches->isNotEmpty()) {
static::whereNotIn('batch_id', $keepBatches)->delete();
}
static::$latestBatchIdCache = $batchId;
// Insert new processes
$rows = [];
foreach ($processes as $index => $proc) {
static::create([
$rows[] = [
'batch_id' => $batchId,
'rank' => $index + 1,
'pid' => $proc['pid'] ?? 0,
@@ -57,7 +66,11 @@ class ServerProcess extends Model
'cpu' => $proc['cpu'] ?? 0,
'memory' => $proc['memory'] ?? 0,
'captured_at' => $now,
]);
];
}
if ($rows) {
static::insert($rows);
}
return $batchId;

View File

@@ -95,6 +95,9 @@ class SysstatMetrics
$samples = [];
$current = $start->startOfDay();
$lastDay = $end->startOfDay();
$startTimestamp = $start->getTimestamp();
$endTimestamp = $end->getTimestamp();
$useDailyCache = ($endTimestamp - $startTimestamp) > 21600;
while ($current <= $lastDay) {
$fileLong = sprintf('/var/log/sysstat/sa%s', $current->format('Ymd'));
@@ -106,15 +109,22 @@ class SysstatMetrics
continue;
}
$dayStart = $current->isSameDay($start) ? $start : $current->startOfDay();
$dayEnd = $current->isSameDay($end) ? $end : $current->endOfDay();
$statistics = $this->readSadf($file, $dayStart, $dayEnd, $options);
if ($useDailyCache) {
$statistics = $this->readSadfDay($file, $current, $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) {
$parsed = $this->parseSample($stat);
if ($parsed === null) {
continue;
}
if ($parsed['timestamp'] < $startTimestamp || $parsed['timestamp'] > $endTimestamp) {
continue;
}
$samples[] = $parsed;
}
@@ -148,6 +158,8 @@ class SysstatMetrics
],
);
$process = new Process($args);
$process->setTimeout(8);
$process->setIdleTimeout(5);
$process->run();
if (! $process->isSuccessful()) {
@@ -167,6 +179,23 @@ class SysstatMetrics
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>
*/