7 "salmon", "lightcoral", "crimson", "red", "darkred", "orangered",
8 "gold", "orange", "yellow", "darkkhaki", "lime", "green", "greenyellow",
9 "springgreen", "olive", "cyan", "turquoise", "teal", "lightskyblue",
10 "dodgerblue", "royalblue", "blue", "navy", "violet", "fuchsia",
11 "darkviolet", "purple", "deeppink", "gray", "darkslategray", "sandybrown",
12 "goldenrod", "chocolate", "saddlebrown", "maroon", "rosybrown", "sienna",
13 "brown", "dimgray", "mediumvioletred", "indigo", "orchid", "mediumpurple",
14 "steelblue", "powderblue", "lightseagreen", "cadetblue", "aquamarine",
15 "olivedrab", "chartreuse", "darkolivegreen", "tomato", "firebrick"
35 online_connections = null
43 var curr_day = d.getDate();
44 var curr_month = d.getMonth() + 1;
45 var curr_year = d.getFullYear();
46 today = curr_year + "-" + curr_month + "-" + curr_day;
51 function UrlParams(params) {
55 for (var key in params) {
56 if (params.hasOwnProperty(key)) {
57 out.push(key + '=' + encodeURIComponent(params[key]));
65 function Macro(template, values) {
66 return templates[template].replace(/\$(\w+)\;/g,function (s,name) {
71 function ColumnMacro(column, values, macro = "column"){
72 var columnrec = columns[column]
75 if (columnrec.template_name) {
76 macro = columnrec.template_name
78 templatestr = columnrec.template
81 return templatestr.replace(/\$(\w+)\;/g,function (s,name) {
85 return Macro(macro,{VALUE:values[column]})
89 function HeaderMacro(column,macro = "header-column"){
90 var columnrec = columns[column]
92 var alias = columns[column].alias;
96 if (!(alias)) { alias = column }
97 return Macro(macro,{VALUE:alias})
100 function GetApi(onfinish,method,params) {
102 var req = new XMLHttpRequest();
104 req.onreadystatechange = function () {
105 if (this.readyState != 4) return;
106 if (this.status != 200) {
107 setTimeout(OnLoad,30000);
110 res = JSON.parse(this.responseText);
114 var url = urlbase+"?method="+method;
118 url = url + '&' + UrlParams(params)
122 req.open("GET", url, true);
123 req.withCredentials = true;
128 function UpdatePageProps(props) {
130 var logo = document.getElementById("brand");
131 logo.innerText = props["site-header"];
135 for (var i in res["columns"]) {
136 columns[res["columns"][i]["name"]] = {alias:res["columns"][i]["alias"],template:res["columns"][i]["template"],template_name:res["columns"][i]["template_name"]}
139 for (var i in res["templates"]) {
140 var mnemo = res["templates"][i]["mnemo"]
141 var body = res["templates"][i]["body"]
142 templates[mnemo] = body
145 dictionaries = res["dictionaries"]
148 for (var cat in cats) {
151 for (rep in category["reps"]) {
152 report = category["reps"][rep]
153 reps[report["mnemo"]] = report
154 reptext = Macro("menuitem",{ MNEMO:report["mnemo"], NAME:report["name"], DESCR:report["description"] })
155 innerHTML = innerHTML + reptext
157 grouptxt = Macro("menugroup",{ MNEMO:category["mnemo"], NAME:category["name"], DESCR:category["description"], MENUITEM: innerHTML})
158 menuInnerHTML = menuInnerHTML + grouptxt
160 menuInnerHTML = Macro("menuonline",{}) + menuInnerHTML
161 menuHTML = Macro("menu", { MENUGROUP: menuInnerHTML} )
162 var Left = document.getElementById("menu");
163 Left.innerHTML = menuHTML
169 function SetDates() {
170 var inp = document.getElementById("date-from")
171 inp.value = date_from
174 var inp = document.getElementById("date-to")
178 var inp = document.getElementById("report-button")
188 GetApi(UpdatePageProps,"get-base-config",null)
193 function ShowHide(id) {
194 var content = document.getElementById(id);
195 if (content.style.display === "block") {
196 content.style.display = "none";
198 content.style.display = "block";
202 function MergeTR(tr,th, macro = "column") {
205 if (!(th[i].startsWith('_'))) {
206 str = str + ColumnMacro(th[i],tr,macro)
212 function MergeTH(th, macro = "header-column") {
215 if (!(th[i].startsWith('_'))) {
216 str = str + HeaderMacro(th[i])
222 function ProduceRep(res) {
224 current_filter = res["filter"]
225 if (!current_filter) { current_filter = {} }
226 dictionary = res["dictionary"]
228 header_template = res["header"]
229 has_total = res["has_total"]
235 if (has_total == "1") {
241 table_row = Macro("table-row",{DATA:MergeTR(row_data,dictionary)})
242 innerHTML = innerHTML + table_row
245 headerHTML = Macro("header-row",{DATA:MergeTH(dictionary)})
247 if (has_total == "1") {
248 totalHTML = Macro("total-row",{DATA:MergeTR(total,dictionary)})
249 reportHTML = Macro("report-table-total",{HEADER:headerHTML,LINES:innerHTML,TOTAL:totalHTML})
251 reportHTML = Macro("report-table",{HEADER:headerHTML,LINES:innerHTML})
253 var body = document.getElementById("report-body")
254 body.innerHTML = reportHTML;
256 if (reps[current_rep].graph_x) {
258 var config = PrepareGraphDataset(data,reps[current_rep].graph_x,reps[current_rep].graph_y,reps[current_rep].graph_series)
259 config.options.responsive = true
261 config.options.scales = {
273 suggestedMin: 0, // minimum will be 0, unless there is a lower value.
284 function DrawGraph(config) {
285 var ctx = document.getElementById('canvas').getContext('2d')
286 var div = document.getElementById("report-graph");
287 canvas.width = div.style.width;
288 canvas.height = div.style.height;
289 window.Graph = new Chart(ctx, config);
292 function AssignColor(key) {
293 if (assigned_colors[key]) {
294 return assigned_colors[key]
297 if (graph_colors.length) {
298 var idx = Math.floor(Math.random() * graph_colors.length)
299 rand_color = graph_colors[idx]
300 graph_colors.splice(idx,1)
302 rand_color = "darkgray"
304 assigned_colors[key] = rand_color
308 function PrepareGraphDataset(data,graph_x,graph_y,graph_series) {
318 if (key == graph_x) {
319 if (!xvals.includes(Number(rec[key]))) {
320 xvals.push(Number(rec[key]))
323 if (key == graph_series) {
324 if (!series.includes(rec[key])) {
325 series.push(rec[key])
331 xvals.sort(function(a,b) { return a-b; })
334 for (var i in series) {
337 values[i].label = series[i]
338 values[i].fill = true
339 values[i].borderColor = AssignColor(values[i].label)
340 values[i].backgroundColor = AssignColor(values[i].label)
341 for (var j in xvals) {
342 values[i].data[j] = 0
346 for (var k in data) {
352 if (key == graph_x) {
353 xval = Number(rec[key])
355 if (key == graph_y) {
356 yval = Number(rec[key])
358 if (key == graph_series) {
362 var j = xvals.indexOf(xval)
363 var i = series.indexOf(dataset)
364 values[i].data[j] = yval
380 function AliasByName(dict,name) {
382 if (dict[i].name == name) { return dict[i].alias }
387 function AddTraffic(label,b) {
389 for (i in online_traffic) {
390 if (online_traffic[i].label == label) {
391 rec = online_traffic[i]
396 rec = { label: label, borderColor: AssignColor(label), backgroundColor: AssignColor(label), data: new Array(online_history).fill(0) }
397 online_traffic.push(rec)
399 rec.data[rec.data.length-1] += b
402 function ProduceOnline(res) {
404 if (!online_traffic) {
409 labels: new Array(online_history).fill('*'),
410 datasets: online_traffic,
426 suggestedMin: 0, // minimum will be 0, unless there is a lower value.
438 for (i = online_traffic.length-1; i>=0; i--) {
439 online_traffic[i].data.shift()
440 online_traffic[i].data.push(0)
441 if (Math.max.apply(null,online_traffic[i].data) == 0) {
442 online_traffic.splice(i,1)
446 dictionary = res["dictionary"]
448 header_template = res["header"]
454 var new_online_connections = []
456 dictionary.unshift("useralias")
459 user = row_data["_user"]
460 username = AliasByName(dictionaries['user_id'],user)
461 row_data["useralias"] = username
463 host = row_data["host"]
464 hostname = AliasByName(dictionaries['host_id'],host)
465 row_data["host"] = hostname
467 table_row = Macro("table-row",{DATA:MergeTR(row_data,dictionary)})
468 innerHTML = innerHTML + table_row
470 var bytes = Number(row_data['bytes'])
472 var idx = row_data["_ip"]+':'+row_data["_port"]
475 if (online_connections) {
476 last_bytes = online_connections[idx]
484 new_online_connections[idx] = bytes
486 AddTraffic(username,bytes-last_bytes)
489 online_connections = new_online_connections
491 headerHTML = Macro("header-row",{DATA:MergeTH(dictionary)})
493 reportHTML = Macro("report-table",{HEADER:headerHTML,LINES:innerHTML})
495 var body = document.getElementById("report-body")
496 body.innerHTML = reportHTML;
498 timer = setTimeout(Online,refresh)
500 window.Graph.update()
504 function CancelRefresh() {
511 function ShowRep(id) {
514 var header = document.getElementById("report-name")
515 header.innerText = reps[id]["name"]
516 var body = document.getElementById("report-body")
517 body.innerText = "Отчет загружается..."
523 function ShowFilteredRep(id,filter) {
526 current_filter[i] = filter[i]
528 var header = document.getElementById("report-name")
529 header.innerText = reps[id]["name"]
530 var body = document.getElementById("report-body")
531 body.innerText = "Отчет загружается..."
537 function FilterSelect(name,dict,value) {
538 var str = '<select onchange="SetFilter(\''+name+'\',this);">'
540 if (dict[key].id==value) {
541 str = str + '<option selected value="'+dict[key].id+'">'+dict[key].name+"</option>"
543 str = str + '<option value="'+dict[key].id+'">'+dict[key].name+"</option>"
546 str = str + "</select>" + Macro("clear-filter",{NAME:name})
552 for (key in current_filter) {
553 var dict = dictionaries[key]
555 str = str + FilterSelect(key,dict,current_filter[key])
557 str = str + Macro("filter-display",{NAME:HeaderMacro(key),VALUE:current_filter[key]}) + Macro("clear-filter",{NAME:key})
563 function RefreshFilterPane() {
564 var filter = document.getElementById("report-dates")
566 filter.style.display = "block";
568 filter.style.display = "none";
570 var filter = document.getElementById("filter")
571 if (Object.keys(current_filter).length === 0) {
572 filter.style.display = "none";
573 filter.innerHTML = ''
575 filter.style.display = "inline-block";
576 filter.innerHTML = Filter()
581 online_traffic = null
582 var parameters = JSON.parse(JSON.stringify(current_filter))
583 parameters["mnemo"] = current_rep
584 parameters["date_from"] = date_from
585 parameters["date_to"] = date_to
586 GetApi(ProduceRep,"report",parameters);
587 var filter = document.getElementById("filter")
594 var header = document.getElementById("report-name")
595 header.innerText = "Активные соединения"
596 GetApi(ProduceOnline,"online",{});
600 function UpdateDates() {
601 var inp = document.getElementById("date-from")
602 date_from = inp.value
603 var inp = document.getElementById("date-to")
610 function SetFilter(name,select) {
611 current_filter[name] = select.value;
614 function ClearFilter(name) {
615 delete current_filter[name];
619 function DisplayGraph(on) {
620 var selector = document.getElementById("page-selector")
622 selector.style.display="block"
624 selector.style.display="none"
625 Display('report-body')
629 function Display(id) {
630 var elements = document.getElementsByClassName('report-block');
631 for (i=0; i<elements.length; i++) {
632 if (elements[i].id == id) {
633 elements[i].style.display = "block"
635 elements[i].style.display = "none"