From 45d1ad17e98661b865e7cd7046a23418624218e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Wed, 22 Jan 2025 19:52:17 +0100 Subject: [PATCH] Clarify interval parameter in stats methods and improve performance logging in authenticator stats report --- server/src/uds/core/managers/stats.py | 2 +- server/src/uds/core/util/stats/counters.py | 2 +- server/src/uds/reports/auto/__init__.py | 1 - server/src/uds/reports/stats/auth_stats.py | 67 ++++++++++++---------- 4 files changed, 38 insertions(+), 34 deletions(-) diff --git a/server/src/uds/core/managers/stats.py b/server/src/uds/core/managers/stats.py index f2a7435ca..3696258c1 100644 --- a/server/src/uds/core/managers/stats.py +++ b/server/src/uds/core/managers/stats.py @@ -145,7 +145,7 @@ class StatsManager(metaclass=singleton.Singleton): owners_ids: Ids of the owners to get counters from. If None, all owners will be used since: date from what to obtain counters. Unlimited if not specified to: date until obtain counters. Unlimited if not specified - interval: Interval to get counters. If None, all counters will be returned + interval: Interval in seconds to get counters. If None, all counters will be returned max_intervals: Maximum number of intervals to get. If None, all intervals will be returned limit: Maximum number of counters to get. If None, all counters will be returned use_max: If True, the maximum value of the counter will be returned instead of the sum diff --git a/server/src/uds/core/util/stats/counters.py b/server/src/uds/core/util/stats/counters.py index 6be817364..db0462e33 100644 --- a/server/src/uds/core/util/stats/counters.py +++ b/server/src/uds/core/util/stats/counters.py @@ -173,7 +173,7 @@ def enumerate_counters( counter_type: Type of counter to get since: From when to get counters to: To when to get counters - interval: Interval to get counters + interval: Interval in seconds to get counters max_intervals: Max intervals to get limit: Max number of results to get use_max: If limit is reached, use max_intervals to get more results diff --git a/server/src/uds/reports/auto/__init__.py b/server/src/uds/reports/auto/__init__.py index c1e0a1aaa..5d4443ea9 100644 --- a/server/src/uds/reports/auto/__init__.py +++ b/server/src/uds/reports/auto/__init__.py @@ -163,7 +163,6 @@ class ReportAuto(Report, metaclass=ReportAutoType): intervals.append((start, next)) start = next - logger.debug('Intervals: %s', intervals) return intervals def adjust_date(self, d: datetime.date, is_ending_date: bool) -> datetime.date: diff --git a/server/src/uds/reports/stats/auth_stats.py b/server/src/uds/reports/stats/auth_stats.py index ba982d026..8e87ff6f7 100644 --- a/server/src/uds/reports/stats/auth_stats.py +++ b/server/src/uds/reports/stats/auth_stats.py @@ -29,7 +29,9 @@ """ Author: Adolfo Gómez, dkmaster at dkmon dot com """ +import datetime import logging +import time import typing from django.utils.translation import gettext, gettext_lazy as _ @@ -62,58 +64,61 @@ class AuthenticatorsStats(StatsReportAuto): uuid = 'a5a43bc0-d543-11ea-af8f-af01fa65994e' def generate(self) -> bytes: - stats: list[dict[str, typing.Any]] = [] + + exec_start = time.time() + + interval = self.get_interval_as_hours() * 3600 # Convert to seconds + + start = datetime.datetime.combine(self.starting_date(), datetime.time.min) + to = datetime.datetime.combine(self.ending_date(), datetime.time.max) + for a in self.get_model_records(): # Will show a.name on every change... stats.append({'date': a.name, 'users': None}) - for i in self.get_intervals_list(): - start = i[0] - end = i[1] - data = [0, 0, 0] - # Get stats for interval - for counter in counters.enumerate_counters( - typing.cast('models.Authenticator', a), + auth = typing.cast('models.Authenticator', a) + + for counter1, counter2, counter3 in zip( + counters.enumerate_counters( + auth, counters.types.stats.CounterType.AUTH_SERVICES, since=start, - to=end, - interval=BIG_INTERVAL, + to=to, + interval=interval, limit=MAX_ELEMENTS, use_max=True, - ): - data[0] += counter[1] - - for counter in counters.enumerate_counters( - typing.cast('models.Authenticator', a), + ), + counters.enumerate_counters( + auth, counters.types.stats.CounterType.AUTH_USERS_WITH_SERVICES, since=start, - to=end, - interval=BIG_INTERVAL, + to=to, + interval=interval, limit=MAX_ELEMENTS, use_max=True, - ): - data[1] += counter[1] - for counter in counters.enumerate_counters( - typing.cast('models.Authenticator', a), + ), + counters.enumerate_counters( + auth, counters.types.stats.CounterType.AUTH_USERS, since=start, - to=end, - interval=BIG_INTERVAL, + to=to, + interval=interval, limit=MAX_ELEMENTS, use_max=True, - ): - data[2] += counter[1] - + ), + ): stats.append( { - 'date': self.format_datetime_as_string(start), - 'users': data[0], - 'services': data[1], - 'user_services': data[2], + 'date': self.format_datetime_as_string(counter1[0]), + 'users': counter3[1], + 'services': counter1[1], + 'user_services': counter2[1], } ) - logger.debug('Report Data Done') + + logger.debug('Report Data Done. Elapsed time: %s', time.time() - exec_start) + return self.template_as_pdf( 'uds/reports/stats/authenticator_stats.html', dct={'data': stats},