From 4ca2aa6cd852e3df74ab7cdfb82382dba8a93867 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 20 Oct 2022 23:27:09 +1100 Subject: [PATCH] Housekeeping Settings (#3821) * Add new settings for controlling how long logged data is retained * Update existing tasks to use new user-configurable values - Also add a task to delete failed task logs * Add background task to remove old notification logs --- InvenTree/InvenTree/tasks.py | 85 ++++++++++++++++--- InvenTree/common/models.py | 33 +++++++ .../templates/InvenTree/settings/global.html | 4 + 3 files changed, 110 insertions(+), 12 deletions(-) diff --git a/InvenTree/InvenTree/tasks.py b/InvenTree/InvenTree/tasks.py index 1c856bebba2b..b1c90008eca9 100644 --- a/InvenTree/InvenTree/tasks.py +++ b/InvenTree/InvenTree/tasks.py @@ -226,22 +226,51 @@ def heartbeat(): @scheduled_task(ScheduledTask.DAILY) def delete_successful_tasks(): - """Delete successful task logs which are more than a month old.""" + """Delete successful task logs which are older than a specified period""" try: from django_q.models import Success + + from common.models import InvenTreeSetting + + days = InvenTreeSetting.get_setting('INVENTREE_DELETE_TASKS_DAYS', 30) + threshold = timezone.now() - timedelta(days=days) + + # Delete successful tasks + results = Success.objects.filter( + started__lte=threshold + ) + + if results.count() > 0: + logger.info(f"Deleting {results.count()} successful task records") + results.delete() + except AppRegistryNotReady: # pragma: no cover logger.info("Could not perform 'delete_successful_tasks' - App registry not ready") - return - threshold = timezone.now() - timedelta(days=30) - results = Success.objects.filter( - started__lte=threshold - ) +@scheduled_task(ScheduledTask.DAILY) +def delete_failed_tasks(): + """Delete failed task logs which are older than a specified period""" + + try: + from django_q.models import Failure + + from common.models import InvenTreeSetting - if results.count() > 0: - logger.info(f"Deleting {results.count()} successful task records") - results.delete() + days = InvenTreeSetting.get_setting('INVENTREE_DELETE_TASKS_DAYS', 30) + threshold = timezone.now() - timedelta(days=days) + + # Delete failed tasks + results = Failure.objects.filter( + started__lte=threshold + ) + + if results.count() > 0: + logger.info(f"Deleting {results.count()} failed task records") + results.delete() + + except AppRegistryNotReady: # pragma: no cover + logger.info("Could not perform 'delete_failed_tasks' - App registry not ready") @scheduled_task(ScheduledTask.DAILY) @@ -250,8 +279,10 @@ def delete_old_error_logs(): try: from error_report.models import Error - # Delete any error logs more than 30 days old - threshold = timezone.now() - timedelta(days=30) + from common.models import InvenTreeSetting + + days = InvenTreeSetting.get_setting('INVENTREE_DELETE_ERRORS_DAYS', 30) + threshold = timezone.now() - timedelta(days=days) errors = Error.objects.filter( when__lte=threshold, @@ -264,7 +295,37 @@ def delete_old_error_logs(): except AppRegistryNotReady: # pragma: no cover # Apps not yet loaded logger.info("Could not perform 'delete_old_error_logs' - App registry not ready") - return + + +@scheduled_task(ScheduledTask.DAILY) +def delete_old_notifications(): + """Delete old notification logs""" + + try: + from common.models import (InvenTreeSetting, NotificationEntry, + NotificationMessage) + + days = InvenTreeSetting.get_setting('INVENTREE_DELETE_NOTIFICATIONS_DAYS', 30) + threshold = timezone.now() - timedelta(days=days) + + items = NotificationEntry.objects.filter( + updated__lte=threshold + ) + + if items.count() > 0: + logger.info(f"Deleted {items.count()} old notification entries") + items.delete() + + items = NotificationMessage.objects.filter( + creation__lte=threshold + ) + + if items.count() > 0: + logger.info(f"Deleted {items.count()} old notification messages") + items.delete() + + except AppRegistryNotReady: + logger.info("Could not perform 'delete_old_notifications' - App registry not ready") @scheduled_task(ScheduledTask.DAILY) diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 582503ae6f4d..25589c4887eb 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -893,6 +893,39 @@ def save(self, *args, **kwargs): 'default': True, }, + 'INVENTREE_DELETE_TASKS_DAYS': { + 'name': _('Delete Old Tasks'), + 'description': _('Background task results will be deleted after specified number of days'), + 'default': 30, + 'units': 'days', + 'validator': [ + int, + MinValueValidator(7), + ] + }, + + 'INVENTREE_DELETE_ERRORS_DAYS': { + 'name': _('Delete Error Logs'), + 'description': _('Error logs will be deleted after specified number of days'), + 'default': 30, + 'units': 'days', + 'validator': [ + int, + MinValueValidator(7) + ] + }, + + 'INVENTREE_DELETE_NOTIFICATIONS_DAYS': { + 'name': _('Delete Noficiations'), + 'description': _('User notifications will be deleted after specified number of days'), + 'default': 30, + 'units': 'days', + 'validator': [ + int, + MinValueValidator(7), + ] + }, + 'BARCODE_ENABLE': { 'name': _('Barcode Support'), 'description': _('Enable barcode scanner support'), diff --git a/InvenTree/templates/InvenTree/settings/global.html b/InvenTree/templates/InvenTree/settings/global.html index 32dee05241d1..aab649b0bcc5 100644 --- a/InvenTree/templates/InvenTree/settings/global.html +++ b/InvenTree/templates/InvenTree/settings/global.html @@ -24,6 +24,10 @@ {% include "InvenTree/settings/setting.html" with key="INVENTREE_REQUIRE_CONFIRM" icon="fa-check" %} {% include "InvenTree/settings/setting.html" with key="INVENTREE_TREE_DEPTH" icon="fa-sitemap" %} {% include "InvenTree/settings/setting.html" with key="INVENTREE_BACKUP_ENABLE" icon="fa-hdd" %} + + {% include "InvenTree/settings/setting.html" with key="INVENTREE_DELETE_TASKS_DAYS" icon="fa-calendar-alt" %} + {% include "InvenTree/settings/setting.html" with key="INVENTREE_DELETE_ERRORS_DAYS" icon="fa-calendar-alt" %} + {% include "InvenTree/settings/setting.html" with key="INVENTREE_DELETE_NOTIFICATIONS_DAYS" icon="fa-calendar-alt" %}