aboutsummaryrefslogtreecommitdiffstats
path: root/interface
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-08 12:06:10 +0000
committerGitHub <noreply@github.com>2017-01-08 12:06:10 +0000
commit95f9bd8b32b17261e168d53a50dd1c9e4d2a752b (patch)
treec7e7b0c4ed26e3c988707807d78b3d16e93f0a5e /interface
parent6bdbf5e9f5ec23bf74baa070ecfacff066d88c1b (diff)
parent7ea6a8c87804ca767864be10ab741b7d0e73e1ae (diff)
downloadrspamd-95f9bd8b32b17261e168d53a50dd1c9e4d2a752b.tar.gz
rspamd-95f9bd8b32b17261e168d53a50dd1c9e4d2a752b.zip
Merge pull request #1318 from moisseev/rrd-summary
[WebUI] Add summary to the Throughput tab
Diffstat (limited to 'interface')
-rw-r--r--interface/css/rspamd.css35
-rw-r--r--interface/index.html90
-rw-r--r--interface/js/rspamd.js143
3 files changed, 197 insertions, 71 deletions
diff --git a/interface/css/rspamd.css b/interface/css/rspamd.css
index 9ec12f2b7..159d6ca50 100644
--- a/interface/css/rspamd.css
+++ b/interface/css/rspamd.css
@@ -538,6 +538,41 @@ td.maps-cell {
padding: 5px 20px 0 20px;
}
+#throughput div.widget-content {
+ text-align: center;
+}
+#throughput div.widget-content > div {
+ display: inline-block;
+}
+#throughput div.widget-content div.row {
+ background: #fff;
+}
+
+/* RRD summary */
+.col-fixed,
+.col-fluid {
+ position: relative;
+ float: left;
+ padding-left: 80px;
+ padding-right: 80px;
+}
+.col-fixed {
+ width: 200px;
+ z-index: 1;
+}
+.col-fluid {
+ width: calc(100% - 200px);
+}
+#rrd-table {
+ width: 100% !important;
+ text-align: left;
+ font-size: 12px;
+}
+#rrd-table td {
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+
/* Throughput graph controls */
#graph_controls select {
margin: 10px 20px 0;
diff --git a/interface/index.html b/interface/index.html
index c303286ee..d73acf7a7 100644
--- a/interface/index.html
+++ b/interface/index.html
@@ -58,7 +58,7 @@
<h5>Statistics</h5>
</div>
<div class="widget-content chart-content">
- <div class="row row-chart">
+ <div class="row">
<div class="chart" id="chart">
<span class="notice">Loading..</span>
<noscript>Please enable Javascript</noscript>
@@ -114,45 +114,59 @@
<span class="icon"><i class="glyphicon glyphicon-stats"></i></span>
<h5>Throughput</h5>
</div>
- <div class="widget-content chart-content">
- <div class="row row-chart">
- <div class="chart" id="graph">
- <span class="notice">Loading..</span>
- <noscript>Please enable Javascript</noscript>
+ <div class="widget-content">
+ <div>
+ <div class="row">
+ <div id="graph">
+ <span class="notice">Loading..</span>
+ <noscript>Please enable Javascript</noscript>
+ </div>
</div>
+
+ <div class="row">
+ <div class="col-fixed" id="rrd-pie" >
+ <span class="notice">Loading..</span>
+ <noscript>Please enable Javascript</noscript>
+ </div>
+
+ <div class="col-fluid">
+ <table id="rrd-table" class="table table-striped table-hover"></table>
+ </div>
+ </div>
+
+ <form id="graph_controls" action="#">
+ Select dataset:
+ <select id="selData" class="form-control">
+ <option value="hourly" selected>Hourly</option>
+ <option value="daily">Daily</option>
+ <option value="weekly">Weekly</option>
+ <option value="monthly">Monthly</option>
+ </select>
+ Convert to:
+ <select id="selConvert" class="form-control">
+ <option value="" selected>--</option>
+ <option value="percentage">percentage</option>
+ </select>
+ Select chart type:
+ <select id="selType" class="form-control">
+ <option value="line" selected>Line</option>
+ <option value="area">Stacked area</option>
+ </select>
+ Select <a title="View Mike Bostock's Block." href="https://bl.ocks.org/mbostock/4342190" target="_blank">interpolation mode</a>:
+ <select id="selInterpolate" class="form-control">
+ <option value="linear" selected>linear</option>
+ <option value="step">step</option>
+ <option value="step-before">step-before</option>
+ <option value="step-after">step-after</option>
+ <option value="basis">basis</option>
+ <option value="basis-open">basis-open</option>
+ <option value="bundle">bundle</option>
+ <option value="cardinal">cardinal</option>
+ <option value="cardinal-open">cardinal-open</option>
+ <option value="monotone">monotone</option>
+ </select>
+ </form>
</div>
- <form id="graph_controls" action="#">
- Select dataset:
- <select id="selData" class="form-control">
- <option value="hourly" selected>Hourly</option>
- <option value="daily">Daily</option>
- <option value="weekly">Weekly</option>
- <option value="monthly">Monthly</option>
- </select>
- Convert to:
- <select id="selConvert" class="form-control">
- <option value="" selected>--</option>
- <option value="percentage">percentage</option>
- </select>
- Select chart type:
- <select id="selType" class="form-control">
- <option value="line" selected>Line</option>
- <option value="area">Stacked area</option>
- </select>
- Select <a title="View Mike Bostock's Block." href="https://bl.ocks.org/mbostock/4342190" target="_blank">interpolation mode</a>:
- <select id="selInterpolate" class="form-control">
- <option value="linear" selected>linear</option>
- <option value="step">step</option>
- <option value="step-before">step-before</option>
- <option value="step-after">step-after</option>
- <option value="basis">basis</option>
- <option value="basis-open">basis-open</option>
- <option value="bundle">bundle</option>
- <option value="cardinal">cardinal</option>
- <option value="cardinal-open">cardinal-open</option>
- <option value="monotone">monotone</option>
- </select>
- </form>
</div>
</div>
</div>
diff --git a/interface/js/rspamd.js b/interface/js/rspamd.js
index 420ca93a7..eec754cb4 100644
--- a/interface/js/rspamd.js
+++ b/interface/js/rspamd.js
@@ -27,6 +27,7 @@
// begin
//$.cookie.json = true;
var pie;
+ var rrd_pie;
var history;
var errors;
var graph;
@@ -63,6 +64,9 @@
if (pie) {
pie.destroy();
}
+ if (rrd_pie) {
+ rrd_pie.destroy();
+ }
if (graph) {
graph.destroy();
graph = undefined;
@@ -617,6 +621,67 @@
return obj;
}
+ var rrd_pie_config = {
+ header: {},
+ size: {
+ canvasWidth: 400,
+ canvasHeight: 180,
+ pieInnerRadius: "20%",
+ pieOuterRadius: "80%"
+ },
+ labels: {
+ outer: {
+ format: "none"
+ },
+ inner: {
+ hideWhenLessThanPercentage: 8
+ },
+ },
+ misc: {
+ pieCenterOffset: {
+ x: -120,
+ y: 10,
+ },
+ gradient: {
+ enabled: true,
+ },
+ },
+ };
+
+ var graph_options = {
+ title: "Rspamd throughput",
+ width: 1060,
+ height: 370,
+ yAxisLabel: "Message rate, msg/s",
+
+ type: selected.selType,
+ interpolate: selected.selInterpolate,
+ convert: selected.selConvert,
+
+ legend: {
+ space: 140,
+ entries: [{
+ label: "Rejected",
+ color: "#FF0000"
+ }, {
+ label: "Temporary rejected",
+ color: "#CC9966"
+ }, {
+ label: "Subject rewrited",
+ color: "#FF6600"
+ }, {
+ label: "Probable spam",
+ color: "#FFD700"
+ }, {
+ label: "Greylisted",
+ color: "#436EEE"
+ }, {
+ label: "Clean",
+ color: "#66cc00"
+ }]
+ }
+ };
+
function initGraph() {
// Get selectors' current state
var selIds = ["selData", "selConvert", "selType", "selInterpolate"];
@@ -625,40 +690,49 @@
selected[id] = e.options[e.selectedIndex].value;
});
- var options = {
- title: "Rspamd throughput",
- width: 1060,
- height: 370,
- yAxisLabel: "Message rate, msg/s",
-
- type: selected.selType,
- interpolate: selected.selInterpolate,
- convert: selected.selConvert,
-
- legend: {
- space: 140,
- entries: [{
- label: "Rejected",
- color: "#FF0000"
- }, {
- label: "Temporary rejected",
- color: "#CC9966"
- }, {
- label: "Subject rewrited",
- color: "#FF6600"
- }, {
- label: "Probable spam",
- color: "#FFD700"
- }, {
- label: "Greylisted",
- color: "#436EEE"
- }, {
- label: "Clean",
- color: "#66cc00"
- }]
+ graph = new D3Evolution("graph", graph_options);
+ }
+
+ function getRrdSummary(json) {
+ const xExtents = d3.extent(d3.merge(json), function (d) { return d.x; });
+ const timeInterval = xExtents[1] - xExtents[0];
+
+ return json.map(function (curr, i) {
+ var avg = d3.mean(curr, function (d) { return d.y; });
+ var yExtents = d3.extent(curr, function (d) { return d.y; });
+
+ return {
+ label: graph_options.legend.entries[i].label,
+ value: avg && (avg * timeInterval) ^ 0,
+ min: yExtents[0],
+ avg: avg && avg.toFixed(6),
+ max: yExtents[1],
+ last: curr[curr.length - 1].y,
+ color: graph_options.legend.entries[i].color,
+ };
+ }, []);
+ }
+
+ function drawRrdTable(data) {
+ $('#rrd-table').DataTable({
+ destroy: true,
+ paging: false,
+ searching: false,
+ info: false,
+ data: data,
+ columns: [
+ { data: "label", title: "Action" },
+ { data: "value", title: "Messages", defaultContent: "" },
+ { data: "min", title: "Minimum, msg/s", defaultContent: "" },
+ { data: "avg", title: "Average, msg/s", defaultContent: "" },
+ { data: "max", title: "Maximum, msg/s", defaultContent: "" },
+ { data: "last", title: "Last, msg/s" },
+ ],
+
+ "fnRowCallback": function (nRow, aData) {
+ $(nRow).css("color", aData.color)
}
- };
- graph = new D3Evolution("graph", options);
+ });
}
function getGraphData(type) {
@@ -674,7 +748,10 @@
xhr.setRequestHeader('Password', getPassword());
},
success: function (data) {
+ const rrd_summary = getRrdSummary(data);
graph.data(data);
+ rrd_pie = drawPie(rrd_pie, "rrd-pie", rrd_summary, rrd_pie_config);
+ drawRrdTable(rrd_summary);
},
error: function (jqXHR, textStatus, errorThrown) {
alertMessage('alert-error', 'Cannot receive throughput data: ' +