diff --git a/server/src/uds/reports/lists/audit.py b/server/src/uds/reports/lists/audit.py index 9e5616eef..f789c3aca 100644 --- a/server/src/uds/reports/lists/audit.py +++ b/server/src/uds/reports/lists/audit.py @@ -36,7 +36,7 @@ import re import typing -from django.db.models import Q +# from django.db.models import Q # disabled for 4.0 (see gen_data) from django.utils.translation import gettext from django.utils.translation import gettext_lazy as _ @@ -84,15 +84,25 @@ def gen_data(self) -> typing.Generator[tuple[typing.Any, typing.Any, typing.Any, r'(?P[^\[ ]*) *(?P.*?): \[(?P[^/]*)/(?P[^\]]*)\] (?P.*)' ) # Marker of config-change entries stored as plain "logs" (from uds.REST.methods.config) - CONFIG_MARKER = 'Updating config value ' + # CONFIG_MARKER = 'Updating config value ' start = self.start_date.as_datetime().replace(hour=0, minute=0, second=0, microsecond=0) end = self.end_date.as_datetime().replace(hour=23, minute=59, second=59, microsecond=999999) + # NOTE: Including config-change entries (LOGS source) requires a data__contains + # filter, which becomes a full-table LIKE '%...%' scan over every Log row. On + # installations with hundreds of millions of rows this is prohibitively slow, so + # it is left disabled for 4.0. Keep the old REST-only filter active. + # for i in Log.objects.filter( + # Q(source=types.log.LogSource.REST) + # | Q(source=types.log.LogSource.LOGS, data__contains=CONFIG_MARKER), + # created__gte=start, + # created__lte=end, + # owner_type=types.log.LogObjectType.SYSLOG, + # ).order_by('-created'): for i in Log.objects.filter( - Q(source=types.log.LogSource.REST) - | Q(source=types.log.LogSource.LOGS, data__contains=CONFIG_MARKER), created__gte=start, created__lte=end, + source=types.log.LogSource.REST, owner_type=types.log.LogObjectType.SYSLOG, ).order_by('-created'): # extract user, method, response_code and request from data field @@ -131,19 +141,20 @@ def gen_data(self) -> typing.Generator[tuple[typing.Any, typing.Any, typing.Any, response_code, m.group('request'), ) - elif CONFIG_MARKER in i.data: - # Config change logged as plain "logs" entry: - # uds.REST.methods.config:put 55 Updating config value
. to by - what = i.data[i.data.index(CONFIG_MARKER) + len(CONFIG_MARKER) :] - value, _sep, user = what.rpartition(' by ') - yield ( - i.created, - '', # no ip recorded for config-change logs - user if _sep else '', - 'CONFIG', - '', - CONFIG_MARKER + (value if _sep else what), - ) + # Disabled for 4.0 along with the LOGS/data__contains filter above (full-scan cost). + # elif CONFIG_MARKER in i.data: + # # Config change logged as plain "logs" entry: + # # uds.REST.methods.config:put 55 Updating config value
. to by + # what = i.data[i.data.index(CONFIG_MARKER) + len(CONFIG_MARKER) :] + # value, _sep, user = what.rpartition(' by ') + # yield ( + # i.created, + # '', # no ip recorded for config-change logs + # user if _sep else '', + # 'CONFIG', + # '', + # CONFIG_MARKER + (value if _sep else what), + # ) def generate(self) -> bytes: output = io.StringIO()