#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.
This commit is contained in:
Florent Dionisi
2009-12-01 18:04:48 +01:00
parent 02d45cc843
commit 6074497a80
7 changed files with 116 additions and 61 deletions
+6 -1
View File
@@ -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"],
+20 -14
View File
@@ -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
+59 -18
View File
@@ -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
})
+7 -7
View File
@@ -49,14 +49,14 @@ window.addEvent("domready", function() {
{% endfor %}
</select>
{% ifequal period "Custom" %}
{% include "stats/calendar.html" %}
{% url extensions.stats.main.adminindex as c_stats_url %}
{% include "stats/calendar.html" %}
{% if start or end %}
<h3>{% trans "Custom period : from" %} {{ start }} {% trans "to" %} {{ end }}</h3>
{% include "stats/graphs.html" %}
{% endif %}
{% else %}
{% include "stats/graphs.html" %}
{% endifequal %}
</div>
<!--
<h2>
{% trans "Period " %}{% trans period %}
</h2>-->
{% include "stats/graphs.html" %}</div>
</div>
{% endblock %}
+21 -20
View File
@@ -1,33 +1,34 @@
{% load i18n %}
<div id="periodSelector" style="border:1px solid #dddddd;float:right;padding:3px;margin-top:-3px;">
<form class="calendarForm" method="post" action="" name="" onSubmit="change()">
{% trans "Start" %}: <input id="dateTravelStart" value="" type="text"/>
{% trans "End" %}: <input id="dateTravelEnd" value="" type="text" />
<input TYPE=SUBMIT VALUE="ok">
</form>
{% url extensions.stats.main.custom_period as c_stats_url %}
<form class="calendarForm" action="{{ c_stats_url }}" method="POST">
<!--<form class="calendarForm" onsubmit="change()">-->
{% trans "Start" %}: <input id="dateTravelStart" name="start" value="{{ start }}" type="text"/>
{% trans "End" %}: <input id="dateTravelEnd" name="end" value="{{ end }}" type="text" />
<input TYPE=SUBMIT VALUE="ok">
</form>
</div>
<script type="text/javascript">
function change() {
alert("New period : start = " + $("dateTravelStart").value + " end = " + $("dateTravelEnd").value);
var dom_sel = $("domain").getElements("option.[selected]")[0].value;
var per_sel = $("period").getElements("option.[selected]")[0].value;
{% url extensions.stats.main.custom_period as c_stats_url %}
alert("url for json : {{ c_stats_url}} ");
location.href = "{{ c_stats_url }}" + "?period=" + per_sel + "&domain=" +
dom_sel + "&start=" + $("dateTravelStart").value +
"&end=" + $("dateTravelEnd").value;
js = new Request.JSON({url: "{{ c_stats_url }}", onSuccess: function(resp) {
alert("html", resp.content);
}}).get({"start" : $("dateTravelStart").value, "end" : $("dateTravelEnd").value});
};
myCal = new Calendar(
myCal = new Calendar(
{
dateTravelStart: 'D, d/m/Y',
dateTravelEnd : 'D, d/m/Y'
dateTravelStart: 'D, Y/m/d',
dateTravelEnd : 'D, Y/m/d'
},
{
direction: 0, // -1 past, 0 past + future, 1 future
pad:1,
offset: 1, // first day of the week: 0 = sunday, 1 = monday, etc..
tweak: {x: -147, y: 18}, // tweak calendar positioning
}
);
{
direction: 0, // -1 past, 0 past + future, 1 future
pad:1,
offset: 1, // first day of the week: 0 = sunday, 1 = monday, etc..
tweak: {x: -147, y: 18} // tweak calendar positioning
});
</script>
<!--
+1 -1
View File
@@ -1,6 +1,6 @@
{% load i18n %}
{% for elems in graphs %}
<h3>{{ elems.label }}</h3>
<p><img src="/static/graphs/{{ elems.name }}_{{ domain }}_AVERAGE_{{ period }}.png"
<p><img src="/static/graphs/{{ elems.name }}_{{ domain }}_AVERAGE_{% ifequal period 'Custom' %}{{ period_name }}{% else %}{{ period }}{% endifequal %}.png"
alt="{% trans 'No statistics available' %}" /></p>
{% endfor %}
+2
View File
@@ -3,6 +3,7 @@
{% block html_head %}
<script src="/static/js/mootools-more.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="/static/stylesheets/box.css" />
<link rel="stylesheet" type="text/css" href="/static/stylesheets/calendar.css" />
<style type="text/css">
#selectors {
float: right;
@@ -17,6 +18,7 @@ window.addEvent("domready", function() {
});
});
</script>
<script type="text/javascript" src="/static/js/calendar.js"></script>
{% endblock %}
{% block menu %}