From bec7a9f449fa3ebb0054efab635e1dceef2ae605 Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Thu, 5 Oct 2023 17:24:28 -0500 Subject: [PATCH] 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 --- app/Providers/ErrorReportingProvider.php | 28 +++++++++++++++++++++++- lang/en/settings.php | 4 ++++ misc/config_definitions.json | 13 ++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/app/Providers/ErrorReportingProvider.php b/app/Providers/ErrorReportingProvider.php index e5a69a0065..27fa5ca024 100644 --- a/app/Providers/ErrorReportingProvider.php +++ b/app/Providers/ErrorReportingProvider.php @@ -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. * diff --git a/lang/en/settings.php b/lang/en/settings.php index 613afee3e4..a9b8a2fd5a 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -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', diff --git a/misc/config_definitions.json b/misc/config_definitions.json index 6b2581d517..709d84e069 100644 --- a/misc/config_definitions.json +++ b/misc/config_definitions.json @@ -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",