From 6074497a800730f2472c03cfd368fc5302abbdf6 Mon Sep 17 00:00:00 2001 From: Florent Dionisi Date: Tue, 1 Dec 2009 18:04:48 +0100 Subject: [PATCH] #24 : period selector added for adminmenu stats. TODO : better parsing of POST and GET request parameters in view functions. Add same view for usermenu stats. --- extensions/stats/grapher.py | 7 +- extensions/stats/logparser.py | 34 ++++++---- extensions/stats/main.py | 77 +++++++++++++++++----- extensions/stats/templates/adminindex.html | 14 ++-- extensions/stats/templates/calendar.html | 41 ++++++------ extensions/stats/templates/graphs.html | 2 +- extensions/stats/templates/index.html | 2 + 7 files changed, 116 insertions(+), 61 deletions(-) diff --git a/extensions/stats/grapher.py b/extensions/stats/grapher.py index 439e1273e..c1889b40e 100644 --- a/extensions/stats/grapher.py +++ b/extensions/stats/grapher.py @@ -49,6 +49,10 @@ size_avg_template = { } } +tpl = {'traffic':traffic_avg_template, + 'badtraffic':badtraffic_avg_template, + 'size':size_avg_template} + class Grapher(object): def __init__(self): self.rrd_rootdir = getoption("RRD_ROOTDIR", "/tmp") @@ -57,6 +61,7 @@ class Grapher(object): def process(self, target, suffix, start, end, tpl=traffic_avg_template): rrdfile = "%s/%s.rrd" % (self.rrd_rootdir, target) if not os.path.exists(rrdfile): + print "[graph] no rrd file detected" return ext = "png" path = "%s/%s_%s_%s_%s.%s" % (self.img_rootdir, tpl['name'], @@ -72,7 +77,7 @@ class Grapher(object): lines += ["%s:%spm%s:%s" % (type, v, d["color"], d["legend"].encode("utf-8"))] params = defs + lines - rrdtool.graph(path, + rrdtool.graph(str(path), "--imgformat", "PNG", "--width", tpl["width"], "--height", tpl["height"], diff --git a/extensions/stats/logparser.py b/extensions/stats/logparser.py index 003c7bf44..e2c449822 100755 --- a/extensions/stats/logparser.py +++ b/extensions/stats/logparser.py @@ -35,6 +35,25 @@ points_per_sample = 3 variables = ["sent", "recv", "bounced", "reject", "spam", "virus", "size_sent", "size_recv"] +def str2Time(y, M, d, h ="0", m ="0", s="0"): + """str2Time + + return epoch time from Year Month Day Hour:Minute:Second time format + """ + try: + local = time.strptime("%s %s %s %s:%s:%s" %(y, M, d, h, m, s), \ + "%Y %b %d %H:%M:%S") + except: + # try with 01-12 month format + try: + local = time.strptime("%s %s %s %s:%s:%s" %(y, M, d, h, m, s), \ + "%Y %m %d %H:%M:%S") + except: + print "[rrd] ERROR unrecognized %s time format" %(y, M, d, h, m, s) + return 0 + return int(time.mktime(local)) + + class LogParser(object): def __init__(self, logfile, workdir, year=None, debug=False, verbose=False): @@ -65,19 +84,6 @@ class LogParser(object): self.lupdates = {} self.line_expr = re.compile("(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\w+)\s+(\w+)/?\w*[[](\d+)[]]:\s+(.*)") - def str2Time(self, y, M, d, h, m, s): - """str2Time - - return epoch time from Year Month Day Hour:Minute:Second time format - """ - try: - local = time.strptime("%s %s %s %s:%s:%s" %(y, M, d, h, m, s), \ - "%Y %b %d %H:%M:%S") - except: - print "[rrd] ERROR unrecognized %s time format" %(y, M, d, h, m, s) - return 0 - return int(time.mktime(local)) - def init_rrd(self, fname, m): """init_rrd @@ -198,7 +204,7 @@ class LogParser(object): se = int(int(se) / rrdstep) # rrd step is one-minute => se = 0 if prev_se != se or prev_mi != mi or prev_ho != ho: - cur_t = self.str2Time(self.year, mo, da, ho, mi, se) + cur_t = str2Time(self.year, mo, da, ho, mi, se) cur_t = cur_t - cur_t % rrdstep prev_mi = mi prev_ho = ho diff --git a/extensions/stats/main.py b/extensions/stats/main.py index d25825bb4..b59217344 100644 --- a/extensions/stats/main.py +++ b/extensions/stats/main.py @@ -16,9 +16,16 @@ from mailng.admin.views import good_domain from mailng.admin.models import Domain, Mailbox from django.contrib.auth.decorators \ import login_required, user_passes_test, permission_required +from extensions.stats.grapher import Grapher,tpl +from extensions.stats.logparser import str2Time graph_types = ['AVERAGE', 'MAX'] +graph_list = [{"name" : "traffic", "label" : _("Average normal traffic")}, + {"name" : "badtraffic", "label" : _("Average bad traffic")}, + {"name" : "size", "label" : _("Average normal traffic size")}] + + def init(): events.register("AdminMenuDisplay", menu) parameters.register("stats", "LOGFILE", "string", "/var/log/mail.log", @@ -100,9 +107,7 @@ def adminindex(request): domains = Domain.objects.all() return _render(request, 'stats/adminindex.html', { "domains" : domains, "domain" : domain, - "graphs" : [{"name" : "traffic", "label" : _("Average normal traffic")}, - {"name" : "badtraffic", "label" : _("Average bad traffic")}, - {"name" : "size", "label" : _("Average normal traffic size")}], + "graphs" : graph_list, "periods" : ["day", "week", "month", "year","Custom"], "period" : period, "cal" : CH_print }) @@ -110,18 +115,56 @@ def adminindex(request): @login_required @user_passes_test(lambda u: u.is_superuser) def custom_period(request): - print "[stats] json get" - start = request.GET.has_key("start") - if not start: - print "[stats] no start selected" - return - end = request.GET.has_key("end") - return _render(request, 'stats/graphs.html', { - "domain" : domain, - "graphs" : [{"name" : "traffic", "label" : _("Average normal traffic")}, - {"name" : "badtraffic", "label" : _("Average bad traffic")}, - {"name" : "size", "label" : _("Average normal traffic size")}], - "period" : "%s_%s" %(start,end) + start = None + end = None + start_ref = None + end_ref = None + domains = Domain.objects.all() + domain = request.GET.has_key("domain") and request.GET["domain"] or "global" + period = request.GET.has_key("period") and request.GET["period"] or "Custom" + + if domain != "global": + domain = Domain.objects.get(pk=domain) + domain = domain.name + try: + start_ref = str(request.POST.get('start')) + start = start_ref.split(', ')[1] + end_ref = str(request.POST.get('end')) + end = end_ref.split(', ')[1] + except: + pass + + if not end or not start: + return _render(request, 'stats/adminindex.html', { + "domains" : domains, "domain" : domain, + "graphs" : graph_list, + "period" : period, + "periods" : ["day", "week", "month", "year","Custom"], + "period_name":None, + "start" : start_ref, + "end" : end_ref, + "messages" : ["Custom period not selected"] + }) + + period_name = "%s_%s" %(start.replace('/',''),end.replace('/','')) + G = Grapher() + for tpl_name in graph_list: + G.process(domain, + period_name, + str2Time(*start.split('/')), + str2Time(*end.split('/')), + tpl[tpl_name['name']]) + + print "[stats] ", period + return _render(request, 'stats/adminindex.html', { + "domains" : domains, "domain" : domain, + "graphs" : graph_list, + "period" : period, + "periods" : ["day", "week", "month", "year","Custom"], + "period_name": period_name, + "start" : start_ref, + "end" : end_ref, + "messages" : None }) @login_required @@ -135,9 +178,7 @@ def index(request, dom_id=None): return _render(request, 'stats/index.html', { "domain" : domain, - "graphs" : [{"name" : "traffic", "label" : _("Average normal traffic")}, - {"name" : "badtraffic", "label" : _("Average bad traffic")}, - {"name" : "size", "label" : _("Average normal traffic size")}], + "graphs" : graph_list, "periods" : ["day", "week", "month", "year","Custom"], "period" : period }) diff --git a/extensions/stats/templates/adminindex.html b/extensions/stats/templates/adminindex.html index 1f170898f..815ae4907 100644 --- a/extensions/stats/templates/adminindex.html +++ b/extensions/stats/templates/adminindex.html @@ -49,14 +49,14 @@ window.addEvent("domready", function() { {% endfor %} {% ifequal period "Custom" %} - {% include "stats/calendar.html" %} - {% url extensions.stats.main.adminindex as c_stats_url %} + {% include "stats/calendar.html" %} + {% if start or end %} +

{% trans "Custom period : from" %} {{ start }} {% trans "to" %} {{ end }}

+ {% include "stats/graphs.html" %} + {% endif %} + {% else %} + {% include "stats/graphs.html" %} {% endifequal %} - - {% include "stats/graphs.html" %} {% endblock %} diff --git a/extensions/stats/templates/calendar.html b/extensions/stats/templates/calendar.html index d48d2bfff..90b302eb5 100644 --- a/extensions/stats/templates/calendar.html +++ b/extensions/stats/templates/calendar.html @@ -1,33 +1,34 @@ {% load i18n %}
-
- {% trans "Start" %}: - {% trans "End" %}: - -
+ {% url extensions.stats.main.custom_period as c_stats_url %} +
+ + {% trans "Start" %}: + {% trans "End" %}: + +