Merge pull request #13181 from jbradberry/remove-qsstats

Replace the querysets provided by django-qsstats-magic
This commit is contained in:
Jeff Bradberry
2022-11-11 10:58:51 -05:00
committed by GitHub
5 changed files with 40 additions and 49 deletions

View File

@@ -5,6 +5,7 @@
import dateutil import dateutil
import functools import functools
import html import html
import itertools
import logging import logging
import re import re
import requests import requests
@@ -20,9 +21,10 @@ from urllib3.exceptions import ConnectTimeoutError
# Django # Django
from django.conf import settings from django.conf import settings
from django.core.exceptions import FieldError, ObjectDoesNotExist from django.core.exceptions import FieldError, ObjectDoesNotExist
from django.db.models import Q, Sum from django.db.models import Q, Sum, Count
from django.db import IntegrityError, ProgrammingError, transaction, connection from django.db import IntegrityError, ProgrammingError, transaction, connection
from django.db.models.fields.related import ManyToManyField, ForeignKey from django.db.models.fields.related import ManyToManyField, ForeignKey
from django.db.models.functions import Trunc
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.timezone import now from django.utils.timezone import now
@@ -47,9 +49,6 @@ from rest_framework import status
from rest_framework_yaml.parsers import YAMLParser from rest_framework_yaml.parsers import YAMLParser
from rest_framework_yaml.renderers import YAMLRenderer from rest_framework_yaml.renderers import YAMLRenderer
# QSStats
import qsstats
# ANSIConv # ANSIConv
import ansiconv import ansiconv
@@ -283,30 +282,50 @@ class DashboardJobsGraphView(APIView):
success_query = success_query.filter(instance_of=models.ProjectUpdate) success_query = success_query.filter(instance_of=models.ProjectUpdate)
failed_query = failed_query.filter(instance_of=models.ProjectUpdate) failed_query = failed_query.filter(instance_of=models.ProjectUpdate)
success_qss = qsstats.QuerySetStats(success_query, 'finished') end = now()
failed_qss = qsstats.QuerySetStats(failed_query, 'finished') interval = 'day'
start_date = now()
if period == 'month': if period == 'month':
end_date = start_date - dateutil.relativedelta.relativedelta(months=1) start = end - dateutil.relativedelta.relativedelta(months=1)
interval = 'days'
elif period == 'two_weeks': elif period == 'two_weeks':
end_date = start_date - dateutil.relativedelta.relativedelta(weeks=2) start = end - dateutil.relativedelta.relativedelta(weeks=2)
interval = 'days'
elif period == 'week': elif period == 'week':
end_date = start_date - dateutil.relativedelta.relativedelta(weeks=1) start = end - dateutil.relativedelta.relativedelta(weeks=1)
interval = 'days'
elif period == 'day': elif period == 'day':
end_date = start_date - dateutil.relativedelta.relativedelta(days=1) start = end - dateutil.relativedelta.relativedelta(days=1)
interval = 'hours' interval = 'hour'
else: else:
return Response({'error': _('Unknown period "%s"') % str(period)}, status=status.HTTP_400_BAD_REQUEST) return Response({'error': _('Unknown period "%s"') % str(period)}, status=status.HTTP_400_BAD_REQUEST)
dashboard_data = {"jobs": {"successful": [], "failed": []}} dashboard_data = {"jobs": {"successful": [], "failed": []}}
for element in success_qss.time_series(end_date, start_date, interval=interval):
dashboard_data['jobs']['successful'].append([time.mktime(element[0].timetuple()), element[1]]) succ_list = dashboard_data['jobs']['successful']
for element in failed_qss.time_series(end_date, start_date, interval=interval): fail_list = dashboard_data['jobs']['failed']
dashboard_data['jobs']['failed'].append([time.mktime(element[0].timetuple()), element[1]])
qs_s = (
success_query.filter(finished__range=(start, end))
.annotate(d=Trunc('finished', interval, tzinfo=end.tzinfo))
.order_by()
.values('d')
.annotate(agg=Count('id', distinct=True))
)
data_s = {item['d']: item['agg'] for item in qs_s}
qs_f = (
failed_query.filter(finished__range=(start, end))
.annotate(d=Trunc('finished', interval, tzinfo=end.tzinfo))
.order_by()
.values('d')
.annotate(agg=Count('id', distinct=True))
)
data_f = {item['d']: item['agg'] for item in qs_f}
start_date = start.replace(hour=0, minute=0, second=0, microsecond=0)
for d in itertools.count():
date = start_date + dateutil.relativedelta.relativedelta(days=d)
if date > end:
break
succ_list.append([time.mktime(date.timetuple()), data_s.get(date, 0)])
fail_list.append([time.mktime(date.timetuple()), data_f.get(date, 0)])
return Response(dashboard_data) return Response(dashboard_data)

View File

@@ -466,7 +466,7 @@ class AutoscalePool(WorkerPool):
task_name = 'unknown' task_name = 'unknown'
if isinstance(body, dict): if isinstance(body, dict):
task_name = body.get('task') task_name = body.get('task')
logger.warn(f'Workers maxed, queuing {task_name}, load: {sum(len(w.managed_tasks) for w in self.workers)} / {len(self.workers)}') logger.warning(f'Workers maxed, queuing {task_name}, load: {sum(len(w.managed_tasks) for w in self.workers)} / {len(self.workers)}')
return super(AutoscalePool, self).write(preferred_queue, body) return super(AutoscalePool, self).write(preferred_queue, body)
except Exception: except Exception:
for conn in connections.all(): for conn in connections.all():

View File

@@ -1,24 +0,0 @@
Copyright (c) 2010, Matt Croydon, Mikhail Korobov
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the tastypie nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL MATT CROYDON BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -19,7 +19,6 @@ django-guid==3.2.1
django-oauth-toolkit==1.4.1 django-oauth-toolkit==1.4.1
django-polymorphic django-polymorphic
django-pglocks django-pglocks
django-qsstats-magic
django-redis django-redis
django-solo django-solo
django-split-settings django-split-settings

View File

@@ -115,9 +115,6 @@ django-pglocks==1.0.4
# via -r /awx_devel/requirements/requirements.in # via -r /awx_devel/requirements/requirements.in
django-polymorphic==3.1.0 django-polymorphic==3.1.0
# via -r /awx_devel/requirements/requirements.in # via -r /awx_devel/requirements/requirements.in
django-qsstats-magic==1.1.0
# via -r /awx_devel/requirements/requirements.in
# via -r /awx_devel/requirements/requirements_git.txt
django-redis==4.5.0 django-redis==4.5.0
# via -r /awx_devel/requirements/requirements.in # via -r /awx_devel/requirements/requirements.in
django-solo==2.0.0 django-solo==2.0.0