mirror of https://github.com/jumpserver/jumpserver
perf: Use user report api
parent
9fbf130640
commit
20c6a6510f
|
@ -1 +1,2 @@
|
||||||
from .report import *
|
from .report import *
|
||||||
|
from .users import *
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
from .user import *
|
|
@ -21,6 +21,7 @@ class UserReportApi(APIView):
|
||||||
http_method_names = ['get']
|
http_method_names = ['get']
|
||||||
# TODO: Define the required RBAC permissions for this API
|
# TODO: Define the required RBAC permissions for this API
|
||||||
rbac_perms = {
|
rbac_perms = {
|
||||||
|
'GET': 'users..view_users',
|
||||||
}
|
}
|
||||||
permission_classes = [RBACPermission, IsValidLicense]
|
permission_classes = [RBACPermission, IsValidLicense]
|
||||||
|
|
||||||
|
@ -46,15 +47,13 @@ class UserReportApi(APIView):
|
||||||
date_range_bounds = self.days_to_datetime.date(), (local_now() + timezone.timedelta(days=1)).date()
|
date_range_bounds = self.days_to_datetime.date(), (local_now() + timezone.timedelta(days=1)).date()
|
||||||
return queryset.filter(**{f'{field_name}__range': date_range_bounds})
|
return queryset.filter(**{f'{field_name}__range': date_range_bounds})
|
||||||
|
|
||||||
def get_user_login_metrics(self):
|
def get_user_login_metrics(self, status):
|
||||||
filtered_queryset = self.filter_by_date_range(self.user_login_log_queryset, 'datetime')
|
queryset = UserLoginLog.objects.filter(status=status)
|
||||||
|
queryset = UserLoginLog.filter_login_queryset_by_org(queryset)
|
||||||
data = defaultdict(set)
|
filtered_queryset = self.filter_by_date_range(queryset, 'datetime').values(
|
||||||
for t, username in filtered_queryset.values_list('datetime', 'username'):
|
'datetime__date').annotate(user_count=Count('username', distinct=True)).order_by('datetime__date')
|
||||||
date_str = str(t.date())
|
result_dict = {r['datetime__date']: r['user_count'] for r in filtered_queryset}
|
||||||
data[date_str].add(username)
|
metrics = [result_dict.get(d, 0) for d in self.date_range_list]
|
||||||
|
|
||||||
metrics = [len(v) for __, v in data]
|
|
||||||
return metrics
|
return metrics
|
||||||
|
|
||||||
def get_user_login_method_metrics(self):
|
def get_user_login_method_metrics(self):
|
||||||
|
@ -66,11 +65,12 @@ class UserReportApi(APIView):
|
||||||
backends.add(backend)
|
backends.add(backend)
|
||||||
date_str = str(t.date())
|
date_str = str(t.date())
|
||||||
data[date_str][backend].add(username)
|
data[date_str][backend].add(username)
|
||||||
|
|
||||||
metrics = defaultdict(list)
|
metrics = defaultdict(list)
|
||||||
for backend in backends:
|
for t in self.date_range_list:
|
||||||
for date_str, usernames in data.items():
|
date_str = str(t)
|
||||||
metrics[backend].append(len(usernames.get(backend, set())))
|
for backend in backends:
|
||||||
|
username = data.get(date_str) if data.get(date_str) else {backend: set()}
|
||||||
|
metrics[backend].append(len(username.get(backend, set())))
|
||||||
return metrics
|
return metrics
|
||||||
|
|
||||||
def get_user_login_region_distribution(self):
|
def get_user_login_region_distribution(self):
|
||||||
|
@ -79,36 +79,50 @@ class UserReportApi(APIView):
|
||||||
data = filtered_queryset.values('city').annotate(
|
data = filtered_queryset.values('city').annotate(
|
||||||
user_count=Count('username', distinct=True)
|
user_count=Count('username', distinct=True)
|
||||||
).order_by('-user_count')
|
).order_by('-user_count')
|
||||||
return list(data)
|
metrics = [{'name': d['city'], 'value': d['user_count']} for d in data]
|
||||||
|
return metrics
|
||||||
|
|
||||||
|
def get_user_login_time_metrics(self):
|
||||||
|
time_buckets = {
|
||||||
|
'00:00-06:00': (0, 6),
|
||||||
|
'06:00-12:00': (6, 12),
|
||||||
|
'12:00-18:00': (12, 18),
|
||||||
|
'18:00-24:00': (18, 24),
|
||||||
|
}
|
||||||
|
filtered_queryset = self.filter_by_date_range(self.user_login_log_queryset, 'datetime').all()
|
||||||
|
metrics = {bucket: 0 for bucket in time_buckets.keys()}
|
||||||
|
for date in filtered_queryset:
|
||||||
|
hour = date.datetime.hour
|
||||||
|
for bucket, (start, end) in time_buckets.items():
|
||||||
|
if start <= hour < end:
|
||||||
|
metrics[bucket] = metrics.get(bucket, 0) + 1
|
||||||
|
return metrics
|
||||||
|
|
||||||
@lazyproperty
|
@lazyproperty
|
||||||
def user_login_log_queryset(self):
|
def user_login_log_queryset(self):
|
||||||
queryset = UserLoginLog.objects.filter(status=LoginStatusChoices.success)
|
queryset = UserLoginLog.objects.filter(status=LoginStatusChoices.success)
|
||||||
return UserLoginLog.filter_login_queryset_by_org(queryset)
|
return UserLoginLog.filter_login_queryset_by_org(queryset)
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def user_login_failed_queryset(self):
|
||||||
|
queryset = UserLoginLog.objects.filter(status=LoginStatusChoices.failed)
|
||||||
|
return UserLoginLog.filter_login_queryset_by_org(queryset)
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
query_params = self.request.query_params
|
|
||||||
data = {}
|
data = {}
|
||||||
|
data['user_login_log_metrics'] = {
|
||||||
_all = query_params.get('all')
|
'dates_metrics_date': [date.strftime('%m-%d') for date in self.date_range_list] or ['0'],
|
||||||
|
'dates_metrics_total': self.get_user_login_metrics(LoginStatusChoices.success),
|
||||||
if _all or query_params.get('user_login_log_metrics'):
|
}
|
||||||
metrics = self.get_user_login_metrics()
|
data['user_login_failed_metrics'] = {
|
||||||
data.update({
|
'dates_metrics_date': [date.strftime('%m-%d') for date in self.date_range_list] or ['0'],
|
||||||
'dates_metrics_date': [date.strftime('%m-%d') for date in self.date_range_list] or ['0'],
|
'dates_metrics_total': self.get_user_login_metrics(LoginStatusChoices.failed),
|
||||||
'dates_metrics_total': metrics,
|
}
|
||||||
})
|
data['user_login_method_metrics'] = {
|
||||||
|
'dates_metrics_date': [date.strftime('%m-%d') for date in self.date_range_list] or ['0'],
|
||||||
if _all or query_params.get('user_login_method_metrics'):
|
'dates_metrics_total': self.get_user_login_method_metrics(),
|
||||||
metrics = self.get_user_login_method_metrics()
|
}
|
||||||
data.update({
|
data['user_login_region_distribution'] = self.get_user_login_region_distribution()
|
||||||
'dates_metrics_date': [date.strftime('%m-%d') for date in self.date_range_list] or ['0'],
|
data['user_login_time_metrics'] = self.get_user_login_time_metrics()
|
||||||
'dates_metrics_total': metrics,
|
|
||||||
})
|
|
||||||
|
|
||||||
if _all or query_params.get('user_login_region_distribution'):
|
|
||||||
data.update({
|
|
||||||
'user_login_region_distribution': self.get_user_login_region_distribution(),
|
|
||||||
})
|
|
||||||
|
|
||||||
return JsonResponse(data, status=200)
|
return JsonResponse(data, status=200)
|
||||||
|
|
|
@ -6,4 +6,5 @@ app_name = 'reports'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('reports/', api.ReportViewSet.as_view(), name='report-list'),
|
path('reports/', api.ReportViewSet.as_view(), name='report-list'),
|
||||||
|
path('reports/users/', api.UserReportApi.as_view(), name='user-list')
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue