mirror of
https://github.com/django-q2/django-q2.git
synced 2026-10-03 09:28:12 +08:00
Adds more stats to the qinfo command
* Average execution time * Tasks per day/hour/minute/second * Number of schedules
This commit is contained in:
+45
-1
@@ -1,9 +1,12 @@
|
|||||||
|
from datetime import timedelta
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
# external
|
# external
|
||||||
from blessed import Terminal
|
from blessed import Terminal
|
||||||
|
|
||||||
# django
|
# django
|
||||||
|
from django.db import connection
|
||||||
|
from django.db.models import Sum, F
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
@@ -193,12 +196,42 @@ def info(r=redis_client):
|
|||||||
term = Terminal()
|
term = Terminal()
|
||||||
ping_redis(r)
|
ping_redis(r)
|
||||||
stat = Stat.get_all(r)
|
stat = Stat.get_all(r)
|
||||||
|
# general stats
|
||||||
clusters = len(stat)
|
clusters = len(stat)
|
||||||
workers = 0
|
workers = 0
|
||||||
reincarnations = 0
|
reincarnations = 0
|
||||||
for cluster in stat:
|
for cluster in stat:
|
||||||
workers += len(cluster.workers)
|
workers += len(cluster.workers)
|
||||||
reincarnations += cluster.reincarnations
|
reincarnations += cluster.reincarnations
|
||||||
|
# calculate tasks pm and avg exec time
|
||||||
|
tasks_per = 0
|
||||||
|
per = _('day')
|
||||||
|
exec_time = 0
|
||||||
|
last_tasks = models.Success.objects.filter(stopped__gte=timezone.now() - timedelta(hours=24))
|
||||||
|
tasks_per_day = last_tasks.count()
|
||||||
|
if tasks_per_day > 0:
|
||||||
|
# average execution time over the last 24 hours
|
||||||
|
if not connection.vendor == 'sqlite':
|
||||||
|
exec_time = last_tasks.aggregate(time_taken=Sum(F('stopped') - F('started')))
|
||||||
|
exec_time = exec_time['time_taken'].total_seconds() / tasks_per_day
|
||||||
|
else:
|
||||||
|
# can't sum timedeltas on sqlite
|
||||||
|
for t in last_tasks:
|
||||||
|
exec_time += t.time_taken()
|
||||||
|
exec_time = exec_time / tasks_per_day
|
||||||
|
# tasks per second/minute/hour/day in the last 24 hours
|
||||||
|
if tasks_per_day > 24 * 60 * 60:
|
||||||
|
tasks_per = tasks_per_day / (24 * 60 * 60)
|
||||||
|
per = _('second')
|
||||||
|
elif tasks_per_day > 24 * 60:
|
||||||
|
tasks_per = tasks_per_day / (24 * 60)
|
||||||
|
per = _('minute')
|
||||||
|
elif tasks_per_day > 24:
|
||||||
|
tasks_per = tasks_per_day / 24
|
||||||
|
per = _('hour')
|
||||||
|
else:
|
||||||
|
tasks_per = tasks_per_day
|
||||||
|
# print to terminal
|
||||||
term.clear_eos()
|
term.clear_eos()
|
||||||
col_width = int(term.width / 6)
|
col_width = int(term.width / 6)
|
||||||
print(term.black_on_green(term.center(_('-- {} summary --').format(Conf.PREFIX))))
|
print(term.black_on_green(term.center(_('-- {} summary --').format(Conf.PREFIX))))
|
||||||
@@ -226,6 +259,18 @@ def info(r=redis_client):
|
|||||||
term.move_x(5 * col_width) +
|
term.move_x(5 * col_width) +
|
||||||
term.white(str(models.Failure.objects.count()))
|
term.white(str(models.Failure.objects.count()))
|
||||||
)
|
)
|
||||||
|
print(term.cyan(_('Schedules')) +
|
||||||
|
term.move_x(1 * col_width) +
|
||||||
|
term.white(str(models.Schedule.objects.count())) +
|
||||||
|
term.move_x(2 * col_width) +
|
||||||
|
term.cyan(_('Tasks/{}'.format(per))) +
|
||||||
|
term.move_x(3 * col_width) +
|
||||||
|
term.white('{0:.2f}'.format(tasks_per)) +
|
||||||
|
term.move_x(4 * col_width) +
|
||||||
|
term.cyan(_('Avg time')) +
|
||||||
|
term.move_x(5 * col_width) +
|
||||||
|
term.white('{0:.4f}'.format(exec_time))
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -237,4 +282,3 @@ def ping_redis(r):
|
|||||||
print(term.red('Can not connect to Redis server.'))
|
print(term.red('Can not connect to Redis server.'))
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import pytest
|
import pytest
|
||||||
import redis
|
import redis
|
||||||
|
|
||||||
|
from django_q import async
|
||||||
from django_q.cluster import Cluster
|
from django_q.cluster import Cluster
|
||||||
from django_q.monitor import monitor, Stat, ping_redis
|
from django_q.monitor import monitor, Stat, ping_redis, info
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
def test_monitor():
|
def test_monitor():
|
||||||
assert Stat.get(0).sentinel == 0
|
assert Stat.get(0).sentinel == 0
|
||||||
c = Cluster()
|
c = Cluster()
|
||||||
@@ -22,6 +24,20 @@ def test_monitor():
|
|||||||
assert found_c is True
|
assert found_c is True
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_info():
|
||||||
|
info()
|
||||||
|
do_sync()
|
||||||
|
info()
|
||||||
|
for _ in range(24):
|
||||||
|
do_sync()
|
||||||
|
info()
|
||||||
|
|
||||||
|
|
||||||
|
def do_sync():
|
||||||
|
async('django_q.tests.tasks.countdown', 1, sync=True, save=True)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_ping_redis():
|
def test_ping_redis():
|
||||||
r = redis.StrictRedis(port=6388)
|
r = redis.StrictRedis(port=6388)
|
||||||
|
|||||||
Reference in New Issue
Block a user