File "SlowQueries.php"
Full Path: /var/www/drive/laravel/pulse/src/Recorders/SlowQueries.php
File size: 3.03 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace Laravel\Pulse\Recorders;
use Carbon\CarbonImmutable;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Support\Str;
use Laravel\Pulse\Pulse;
/**
* @internal
*/
class SlowQueries
{
use Concerns\Ignores, Concerns\Sampling, Concerns\Thresholds;
/**
* The events to listen for.
*
* @var class-string
*/
public string $listen = QueryExecuted::class;
/**
* Create a new recorder instance.
*/
public function __construct(
protected Pulse $pulse,
protected Repository $config,
) {
//
}
/**
* Record a slow query.
*/
public function record(QueryExecuted $event): void
{
[$timestampMs, $duration, $sql, $location] = [
CarbonImmutable::now()->getTimestampMs(),
(int) $event->time,
$event->sql,
$this->config->get('pulse.recorders.'.self::class.'.location')
? $this->resolveLocation()
: null,
];
$this->pulse->lazy(function () use ($timestampMs, $duration, $sql, $location) {
if (
! $this->shouldSample() ||
$this->shouldIgnore($sql) ||
$this->underThreshold($duration, $sql)
) {
return;
}
if ($maxQueryLength = $this->config->get('pulse.recorders.'.self::class.'.max_query_length')) {
$sql = Str::limit($sql, $maxQueryLength);
}
$this->pulse->record(
type: 'slow_query',
key: json_encode([$sql, $location], flags: JSON_THROW_ON_ERROR),
value: $duration,
timestamp: (int) (($timestampMs - $duration) / 1000),
)->max()->count();
});
}
/**
* Resolve the location of the query.
*/
protected function resolveLocation(): string
{
$backtrace = collect(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS))->skip(2);
$frame = $backtrace->firstWhere(fn (array $frame) => isset($frame['file']) && ! $this->isInternalFile($frame['file']));
if ($frame === null) {
return '';
}
return $this->formatLocation($frame['file'] ?? 'unknown', $frame['line'] ?? null);
}
/**
* Determine whether a file should be considered internal.
*/
protected function isInternalFile(string $file): bool
{
return Str::startsWith($file, base_path('vendor'.DIRECTORY_SEPARATOR.'laravel'.DIRECTORY_SEPARATOR.'pulse'))
|| Str::startsWith($file, base_path('vendor'.DIRECTORY_SEPARATOR.'laravel'.DIRECTORY_SEPARATOR.'framework'))
|| $file === base_path('artisan')
|| $file === public_path('index.php');
}
/**
* Format a file and line number and strip the base path.
*/
protected function formatLocation(string $file, ?int $line): string
{
return Str::replaceFirst(base_path(DIRECTORY_SEPARATOR), '', $file).(is_int($line) ? (':'.$line) : '');
}
}