Reduce metrics overhead and cache sysstat days
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user