mirror of
https://github.com/ansible/awx.git
synced 2026-05-20 07:17:40 -02:30
Merge pull request #13181 from jbradberry/remove-qsstats
Replace the querysets provided by django-qsstats-magic
This commit is contained in:
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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():
|
||||||
|
|||||||
@@ -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.
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user