mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
#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:
@@ -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"],
|
||||
|
||||
@@ -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
@@ -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
|
||||
})
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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,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 %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
Reference in New Issue
Block a user