diff --git a/app/Http/Controllers/Admin/TelemetryController.php b/app/Http/Controllers/Admin/TelemetryController.php index 7aa60cad8d..2b9163992b 100644 --- a/app/Http/Controllers/Admin/TelemetryController.php +++ b/app/Http/Controllers/Admin/TelemetryController.php @@ -101,7 +101,8 @@ class TelemetryController extends Controller app('view')->share('subTitleIcon', 'fa-eye'); app('view')->share('subTitle', (string) trans('firefly.telemetry_admin_index')); $version = config('firefly.version'); - $enabled = config('firefly.telemetry', false); + $enabled = config('firefly.send_telemetry', false) && config('firefly.feature_flags.telemetry'); + $count = $this->repository->count(); return view('admin.telemetry.index', compact('version', 'enabled', 'count')); diff --git a/app/Support/Telemetry.php b/app/Support/Telemetry.php index 905ca18233..cc9c3aacb6 100644 --- a/app/Support/Telemetry.php +++ b/app/Support/Telemetry.php @@ -22,7 +22,9 @@ declare(strict_types=1); namespace FireflyIII\Support; +use Carbon\Carbon; use FireflyIII\Models\Telemetry as TelemetryModel; +use JsonException; use Log; /** @@ -65,6 +67,25 @@ class Telemetry } } + /** + * @param string $key + * @param string $value + * @param int $days + */ + public function recurring(string $key, string $value, int $days): void + { + if (false === config('firefly.send_telemetry') || false === config('firefly.feature_flags.telemetry')) { + // hard stop if not allowed to do telemetry. + // do nothing! + return; + } + + $cutoffDate = Carbon::today()->subDays($days); + if (!$this->hasRecentEntry('recurring', $key, $value, $cutoffDate)) { + $this->storeEntry('recurring', $key, $value); + } + } + /** * String telemetry stores a string value as a telemetry entry. Values could include: * @@ -85,7 +106,6 @@ class Telemetry } Log::info(sprintf('Logged telemetry string "%s" with value "%s".', $name, $value)); - // no storage backend yet, do nothing. $this->storeEntry('string', $name, $value); } @@ -98,16 +118,49 @@ class Telemetry */ private function hasEntry(string $type, string $key, string $value): bool { + try { + $jsonEncoded = json_encode($value, JSON_THROW_ON_ERROR, 512); + } catch (JsonException $e) { + Log::error(sprintf('JSON Exception encoding the following value: %s: %s', $value, $e->getMessage())); + $jsonEncoded = []; + } + return TelemetryModel ::where('type', $type) ->where('key', $key) - ->where('value', json_encode($value, JSON_THROW_ON_ERROR, 512)) + ->where('value', $jsonEncoded) + ->count() > 0; + } + + /** + * @param string $type + * @param string $key + * @param string $value + * @param Carbon $date + * + * @return bool + */ + private function hasRecentEntry(string $type, string $key, string $value, Carbon $date): bool + { + try { + $jsonEncoded = json_encode($value, JSON_THROW_ON_ERROR, 512); + } catch (JsonException $e) { + Log::error(sprintf('JSON Exception encoding the following value: %s: %s', $value, $e->getMessage())); + $jsonEncoded = []; + } + + return TelemetryModel + ::where('type', $type) + ->where('key', $key) + ->where('created_at', '>=', $date->format('Y-m-d H:i:s')) + ->where('value', $jsonEncoded) ->count() > 0; } /** * Store new entry in DB. * + * @param string $type * @param string $name * @param string $value */ @@ -123,4 +176,4 @@ class Telemetry ); } -} \ No newline at end of file +} diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index b659364402..7bb6ca162b 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -1624,6 +1624,7 @@ return [ 'not_yet_submitted' => 'Not yet submitted', 'telemetry_type_feature' => 'Feature flag', 'telemetry_submit_all' => 'Submit records', + 'telemetry_type_recurring' => 'Recurring', 'telemetry_delete_submitted_records' => 'Delete submitted records', 'telemetry_submission_executed' => 'Records have been submitted. Check your log files for more info.', 'telemetry_all_deleted' => 'All telemetry records have been deleted.',