diff --git a/docs/configuration/optional-settings.md b/docs/configuration/optional-settings.md index 600927394..ce31cfd46 100644 --- a/docs/configuration/optional-settings.md +++ b/docs/configuration/optional-settings.md @@ -44,6 +44,14 @@ BASE_PATH = 'netbox/' --- +## CHANGELOG_RETENTION + +Default: 90 + +The number of days to retain logged changes (object creations, updates, and deletions). Set this to `0` to retain changes in the database indefinitely. (Warning: This will greatly increase database size over time.) + +--- + ## CORS_ORIGIN_ALLOW_ALL Default: False diff --git a/netbox/extras/middleware.py b/netbox/extras/middleware.py index 429d8ed55..e4f04f243 100644 --- a/netbox/extras/middleware.py +++ b/netbox/extras/middleware.py @@ -1,11 +1,17 @@ from __future__ import unicode_literals +from datetime import timedelta +import logging +import random import uuid +from django.conf import settings from django.db.models.signals import post_delete, post_save +from django.utils import timezone from django.utils.functional import curry, SimpleLazyObject from .constants import OBJECTCHANGE_ACTION_CREATE, OBJECTCHANGE_ACTION_DELETE, OBJECTCHANGE_ACTION_UPDATE +from .models import ObjectChange def record_object_change(user, request_id, instance, **kwargs): @@ -24,6 +30,15 @@ def record_object_change(user, request_id, instance, **kwargs): instance.log_change(user, request_id, action) + # 1% chance of clearing out expired ObjectChanges + if settings.CHANGELOG_RETENTION and random.randint(1, 100): + cutoff = timezone.now() - timedelta(days=settings.CHANGELOG_RETENTION) + purged_count, _ = ObjectChange.objects.filter( + time__lt=cutoff + ).delete() + logger = logging.getLogger('django') + logger.info("Automatically purged {} changes past the retention period".format(purged_count)) + class ChangeLoggingMiddleware(object): diff --git a/netbox/netbox/configuration.example.py b/netbox/netbox/configuration.example.py index 27a615c32..23d6ba221 100644 --- a/netbox/netbox/configuration.example.py +++ b/netbox/netbox/configuration.example.py @@ -50,6 +50,9 @@ BANNER_LOGIN = '' # BASE_PATH = 'netbox/' BASE_PATH = '' +# Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90) +CHANGELOG_RETENTION = 90 + # API Cross-Origin Resource Sharing (CORS) settings. If CORS_ORIGIN_ALLOW_ALL is set to True, all origins will be # allowed. Otherwise, define a list of allowed origins using either CORS_ORIGIN_WHITELIST or # CORS_ORIGIN_REGEX_WHITELIST. For more information, see https://github.com/ottoyiu/django-cors-headers diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 83686df94..f526ebf19 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -44,6 +44,7 @@ BANNER_TOP = getattr(configuration, 'BANNER_TOP', '') BASE_PATH = getattr(configuration, 'BASE_PATH', '') if BASE_PATH: BASE_PATH = BASE_PATH.strip('/') + '/' # Enforce trailing slash only +CHANGELOG_RETENTION = getattr(configuration, 'CHANGELOG_RETENTION', 90) CORS_ORIGIN_ALLOW_ALL = getattr(configuration, 'CORS_ORIGIN_ALLOW_ALL', False) CORS_ORIGIN_REGEX_WHITELIST = getattr(configuration, 'CORS_ORIGIN_REGEX_WHITELIST', []) CORS_ORIGIN_WHITELIST = getattr(configuration, 'CORS_ORIGIN_WHITELIST', [])