A warning that fires on every request during an incident is the majority of the log volume and adds nothing after the first hundred.
final class SamplingProcessor
{
public function __invoke(array $record): array|false
{
$rate = self::RATES[$record['message']] ?? 1.0;
return $rate >= 1.0 || random_int(1, 1000) <= $rate * 1000
? $record + ['sampled_at' => $rate]
: false;
}
}
Recording the sample rate on the line that survives is what keeps the counts recoverable — without it, a query counting occurrences under-reports by whatever factor was applied and nobody knows which. Sampling by message rather than globally is what preserves the rare lines, which are the ones worth keeping.