Throttle error reporting (#15391)

* Throttle error reporting
Sets how frequently errors can be reported (across all pollers)
Also has the side effect of at most 1 error reported per run
To disable, set reporting.throttle to 0 (for development and testing purposes)

* Don't crash if Cache provider is unavailable, refactor
This commit is contained in:
Tony Murray
2023-10-05 17:24:28 -05:00
committed by GitHub
parent 366be4cd49
commit bec7a9f449
3 changed files with 43 additions and 2 deletions

View File

@@ -31,6 +31,7 @@ use App\Logging\Reporting\Middleware\SetGroups;
use App\Logging\Reporting\Middleware\SetInstanceId;
use App\Models\Callback;
use ErrorException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use LibreNMS\Config;
@@ -49,8 +50,12 @@ class ErrorReportingProvider extends \Spatie\LaravelIgnition\IgnitionServiceProv
/** @var string|null */
private static $instanceId;
private $throttle = 300;
public function boot(): void
{
$this->throttle = Config::get('reporting.throttle', 300);
/* @phpstan-ignore-next-line */
if (! method_exists(\Spatie\FlareClient\Flare::class, 'filterReportsUsing')) {
Log::debug("Flare client too old, disabling Ignition to avoid bug.\n");
@@ -63,7 +68,8 @@ class ErrorReportingProvider extends \Spatie\LaravelIgnition\IgnitionServiceProv
dump('Exception: ' . $e->getMessage(), $e->getFile() . ':' . $e->getLine());
}
return $this->isReportingEnabled();
// check if reporting is enabled and not throttled
return $this->isReportingEnabled() && ! $this->isThrottled();
});
Flare::filterReportsUsing(function (Report $report) {
@@ -149,6 +155,26 @@ class ErrorReportingProvider extends \Spatie\LaravelIgnition\IgnitionServiceProv
return true;
}
private function isThrottled(): bool
{
if ($this->throttle) {
$this->reportingEnabled = false; // disable future reporting (to avoid this cache check)
try {
if (Cache::get('recently_reported_error')) {
return true; // reporting is currently throttled
}
// let this report go and disable reporting for the next error
Cache::put('recently_reported_error', true, $this->throttle);
} catch (\Exception $e) {
// ignore throttling exception (Such as database or redis not running for cache)
}
}
return false;
}
/**
* Report PHP deprecations, or convert PHP errors to ErrorException instances.
*

View File

@@ -1291,6 +1291,10 @@ return [
'description' => 'Dump debug errors (Will break your install)',
'help' => 'Dump out errors that are normally hidden so you as a developer can find and fix the possible issues.',
],
'throttle' => [
'description' => 'Throttle Error Reports',
'help' => 'Reports will only be sent every specified amount of seconds. Without this if you have an error in common code reporting can get out of hand. Set to 0 to disable throttling.',
],
],
'route_purge' => [
'description' => 'Route entries older than',

View File

@@ -5167,16 +5167,27 @@
}
},
"reporting.error": {
"group": "system",
"section": "reporting",
"order": 1,
"default": false,
"type": "boolean"
},
"reporting.dump_errors": {
"group": "system",
"section": "reporting",
"order": 1,
"order": 2,
"default": false,
"type": "boolean"
},
"reporting.throttle": {
"default": 300,
"type": "integer",
"units": "seconds",
"group": "system",
"section": "reporting",
"order": 3
},
"reporting.usage": {
"group": "system",
"section": "reporting",