New metrics charts
pull/161/head
Pavel Loginov 2019-10-05 23:41:07 +03:00
parent d5eb2b8fbc
commit 30432686ed
15 changed files with 218 additions and 63 deletions

View File

@ -24,8 +24,7 @@ template = template.render(h2 = 1, title = "Metrics",
autorefresh = 1,
role = sql.get_user_role_by_uuid(user_id.value),
user = user,
onclick = "metricsShow()",
table_stat = sql.select_table_metrics(user_id.value),
servers = sql.get_dick_permit(),
versions = funct.versions(),
token = token)
print(template)

View File

@ -9,8 +9,11 @@ import ovw
form = cgi.FieldStorage()
serv = form.getvalue('serv')
act = form.getvalue('act')
print('Content-type: text/html\n')
if form.getvalue('new_metrics'):
print('Content-type: application/json\n')
else:
print('Content-type: text/html\n')
if act == "checkrestart":
servers = sql.get_dick_permit(ip=serv)
@ -436,7 +439,52 @@ if form.getvalue('table_metrics'):
template = template.render(table_stat=sql.select_table_metrics(user_id.value))
print(template)
if form.getvalue('new_metrics'):
from datetime import timedelta
import http.cookies
# cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
# user_id = cookie.get('uuid')
# servers = sql.select_servers_metrics(user_id.value)
# servers = sorted(servers)
serv = form.getvalue('server')
# p = {}
# for serv in servers:
# serv = serv[0]
# p[serv] = {}
metric = sql.select_metrics(serv)
metrics = {}
metrics['chartData'] = {}
metrics['chartData']['labels'] = {}
labels = ''
curr_con = ''
curr_ssl_con = ''
sess_rate = ''
max_sess_rate = ''
for i in metric:
labels += str(i[5].split(' ')[1])+','
curr_con += str(i[1])+','
curr_ssl_con += str(i[2])+','
sess_rate += str(i[3])+','
max_sess_rate += str(i[4])+','
server = str(i[0])
metrics['chartData']['labels'] = labels
# metrics[rep_date]['server'] = str(i[0])
metrics['chartData']['curr_con'] = curr_con
metrics['chartData']['curr_ssl_con'] = curr_ssl_con
metrics['chartData']['sess_rate'] = sess_rate
metrics['chartData']['max_sess_rate'] = max_sess_rate
metrics['chartData']['server'] = server
import json
print(json.dumps(metrics))
if form.getvalue('metrics'):
from datetime import timedelta
from bokeh.plotting import figure, output_file, show

View File

@ -890,7 +890,7 @@ def delete_mentrics():
def select_metrics(serv, **kwargs):
con, cur = create_db.get_cur()
sql = """ select * from metrics where serv = '%s' order by `date` desc """ % serv
sql = """ select * from (select * from metrics where serv = '%s' order by `date` desc limit 30) order by `date` """ % serv
try:
cur.execute(sql)
except sqltool.Error as e:
@ -1513,7 +1513,7 @@ if form.getvalue('getoption'):
print('Content-type: application/json\n')
check_token()
options = select_options(group=group,term=term)
a = ""
a = {}
v = 0
for i in options:

View File

@ -1,5 +1,10 @@
{% extends "base.html" %}
{% block content %}
<style>
.container {
margin-right: 0;
}
</style>
<script src="/inc/add.js"></script>
<div id="tabs">
<ul>

View File

@ -1,5 +1,10 @@
{% extends "base.html" %}
{% block content %}
<style>
.container {
margin-right: 0;
}
</style>
<script src="/inc/users.js"></script>
<script src="/inc/fontawesome.min.js"></script>
<div id="dialog-confirm" title="Are you sure you want to delete?" style="display: none;">
@ -126,7 +131,7 @@
<table class="overview" id="ajax-group">
<tr class="overviewHead">
<td class="padding10 first-collumn">Name</td>
<td>Desciption</td>
<td>Description</td>
<td></td>
</tr>
{% for group in groups %}
@ -158,7 +163,7 @@
<table class="overview" id="group-add-table" style="display: none;">
<tr class="overviewHead">
<td class="padding10 first-collumn">New group name</td>
<td>Desciption</td>
<td>Description</td>
<td></td>
</tr>
<tr>
@ -304,7 +309,7 @@
<!-- <table class="overview" id="ajax-group"> -->
<!-- <tr class="overviewHead"> -->
<!-- <td class="padding10 first-collumn">Name</td> -->
<!-- <td>Desciption</td> -->
<!-- <td>Description</td> -->
<!-- </tr> -->
<!-- <tr> -->
<!-- {% for role in roles %} -->
@ -688,7 +693,7 @@
</td>
</tr>
<tr>
<td class="padding20">Desciption</td>
<td class="padding20">Description</td>
<td>
<input type="text" id="desc" size="30" class="form-control">
</td>

View File

@ -47,8 +47,8 @@
<li class="p_menu"><a title="Actions with Haproxy configs" class="config-show">Haproxy</a>
<ul class="v_menu">
<li><a href=/app/hapservers.py title="Working with Haproxy Configs" class="overview-link head-submenu">Overview</a> </li>
{% if role <= 2 %}
<li><a href=/app/config.py title="Working with HAProxy configs" class="edit head-submenu">Configs</a></li>
{% if role <= 2 %}
<li><a href=/app/add.py#proxy title="Add proxy" class="add head-submenu" id="add1">Add proxy</a></li>
<li><a href=/app/versions.py title="Actions with configs versions" class="version head-submenu">Versions</a></li>
<li><a href=/app/add.py#ssl title="Upload SSL cert" class="cert head-submenu" id="add4">SSL</a></li>

View File

@ -13,33 +13,23 @@ table, th, tr, td {
th, tr, td {
width: 6%;
padding: 10px;
}
.metrics1 {
width: 400px;
height: 100px;}
}
</style>
<script src="/inc/metrics.js"></script>
<div id="table_metrics"></div>
{% for s in servers %}
<canvas id="{{s.2}}" width="100" height="20" class="metrics1" role="img"></canvas>
<script>
getChartData('{{s.2}}')
</script>
{% endfor %}
<div id="metrics_iframe"></div>
<script>
$("#secIntervals").css("display", "none");
function callIframe(url, callback) {
$('#metrics_iframe').html('<iframe id="metrics" style="width:100%;height:100%;" />');
$('iframe#metrics').attr('src', url);
$('iframe#metrics').load(function() {
callback(this);
});
}
function loadMetrics() {
callIframe('templates/metrics_out.html', function(){
$.get( "options.py?metrics=1&token="+$('#token').val(), function( data ) {
$( ".result" ).html( data );
})
$.get( "options.py?table_metrics=1&token="+$('#token').val(), function( data ) {
$( "#table_metrics" ).html( data );
});
});
}
loadMetrics()
loadMetrics()
</script>
{% endblock %}

View File

@ -7,10 +7,7 @@
<tr class="overviewHead">
<td class="padding10 first-collumn-wi">
Server
</td class="padding10 second-collumn">
<!-- <td class="padding10 second-collumn"> -->
<!-- HAproxy status -->
<!-- </td> -->
</td>
<td class="padding10 third-collumn-wi">
Action
</td>
@ -28,9 +25,6 @@
<td class="padding10 first-collumn-wi">
WAF
</td class="padding10 second-collumn">
<!-- <td class="padding10 second-collumn"> -->
<!-- WAF status -->
<!-- </td> -->
<td class="padding10 third-collumn-wi">
Action
</td>
@ -55,11 +49,10 @@
</td>
</tr>
<tr>
<td style="width:90%">
<td style="width:90%" colspan="2">
<pre style="margin: 0;" id="ajaxHapwi">
</pre>
</td>
<td></td>
</tr>
</table>
<table class="overview-wi" style="height: 170;">
@ -75,7 +68,7 @@
{% else %}
<span class="serverDown server-status"></span>
{% endif %}
<a href="/app/viewlogs.py?viewlogs=metrics-error.log&rows=10&grep=&hour=00&minut=00&hour1=24&minut1=00" title="View metrics master's logs" class="logs_link">
<a href="/app/viewlogs.py?viewlogs=metrics-{{date}}.log&rows=10&grep=&hour=00&minut=00&hour1=24&minut1=00" title="View metrics master's logs" class="logs_link">
<span>Metrics master</span>
</a>
</td>
@ -85,7 +78,7 @@
{% else %}
<span class="serverDown server-status"></span>
{% endif %}
<a href="/app/viewlogs.py?viewlogs=checker-error.log&rows=10&grep=&hour=00&minut=00&hour1=24&minut1=00" title="View checker master's logs" class="logs_link">
<a href="/app/viewlogs.py?viewlogs=checker-{{date}}.log&rows=10&grep=&hour=00&minut=00&hour1=24&minut1=00" title="View checker master's logs" class="logs_link">
<span>Checker master</span>
</a>
</td>
@ -107,7 +100,9 @@
{% else %}
<span title="running {{metrics_worker}} worker processes"><span class="serverDown server-status"></span>
{% endif %}
<span>Metrics workers</span>
<a href="/app/viewlogs.py?viewlogs=metrics-error.log&rows=10&grep=&hour=00&minut=00&hour1=24&minut1=00" title="View worker's logs" class="logs_link">
<span>Metrics workers</span>
</a>
</td>
<td>
{% if checker_worker|int() >= 1 %}
@ -115,7 +110,9 @@
{% else %}
<span title="running {{ checker_worker }} worker processes"><span class="serverDown server-status"></span>
{% endif %}
<span>Checker workers</span>
<a href="/app/viewlogs.py?viewlogs=checker-error.log&rows=10&grep=&hour=00&minut=00&hour1=24&minut1=00" title="View checker's logs" class="logs_link">
<span>Checker workers</span>
</a>
</td>
<td></td>
@ -125,7 +122,6 @@
<table class="overview-wi">
<tr class="overviewHead">
<td class="padding10 first-collumn-wi">Login</td>
<!-- <td class="padding10 second-collumn">Email</td> -->
<td class="second-collumn">Group</td>
<td>Role</td>
<td>
@ -153,8 +149,7 @@
<td class="third-collumn-wi">{{ group.1 }}</td>
{% endif %}
{% endfor %}
<td>{{ USER.4 }}</td>
<td></td>
<td colspan="2">{{ USER.4 }}</td>
</tr>
{% else %}
<tr style="display: none;" class="show-users {{ loop.cycle('odd', 'even') }}">
@ -170,8 +165,7 @@
<td class="third-collumn-wi">{{ group.1 }}</td>
{% endif %}
{% endfor %}
<td>{{ USER.4 }}</td>
<td></td>
<td colspan="2">{{ USER.4 }}</td>
</tr>
{% endif %}
{% endfor %}
@ -200,8 +194,7 @@
<img src="/inc/images/edit.png" alt="Edit" width="15" style="margin-bottom: -3px;" />
</a>
</td>
<td class="third-collumn-wi">{{ group.2 }}</td>
<td></td>
<td class="third-collumn-wi" colspan="2">{{ group.2 }}</td>
</tr>
{% else %}
<tr style="display: none;" class="show-groups {{ loop.cycle('odd', 'even') }}">
@ -211,8 +204,7 @@
<img src="/inc/images/edit.png" alt="Edit" width="15" style="margin-bottom: -3px;" />
</a>
</td>
<td class="third-collumn-wi">{{ group.2 }}</td>
<td></td>
<td class="third-collumn-wi" colspan="2">{{ group.2 }}</td>
</tr>
{% endif %}
{% endfor %}

View File

@ -1,5 +1,10 @@
{% extends "base.html" %}
{% block content %}
<style>
.container {
margin-right: 0;
}
</style>
<script src="/inc/users.js"></script>
<div id="dialog-confirm" title="Are you sure you want to delete?" style="display: none;">
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:3px 12px 20px 0;"></span>Deleting irreversibly all data will be lost?</p>

View File

@ -41,7 +41,7 @@ def main(serv, port):
for i in range(0,len(metric)):
sql.insert_waf_mentrics(serv, metric[i])
time.sleep(10)
time.sleep(60)
if killer.kill_now:
break

View File

@ -41,7 +41,7 @@ def main(serv, port):
sql.insert_mentrics(serv, metrics[0], metrics[1], metrics[2], metrics[3])
time.sleep(10)
time.sleep(60)
if killer.kill_now:
break

1
inc/chart.min.css vendored Normal file
View File

@ -0,0 +1 @@
@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}

7
inc/chart.min.js vendored Normal file

File diff suppressed because one or more lines are too long

101
inc/metrics.js Normal file
View File

@ -0,0 +1,101 @@
function getChartData(server) {
$.ajax({
url: "options.py",
data: {
new_metrics: '1',
server: server,
token: $('#token').val()
},
type: "GET",
success: function (result) {
var data = [];
data.push(result.chartData.curr_con);
data.push(result.chartData.curr_ssl_con);
data.push(result.chartData.sess_rate);
data.push(result.chartData.max_sess_rate);
data.push(result.chartData.server);
var labels = result.chartData.labels;
renderChart(data, labels, server);
},
error: function (err) {
$("#loadingMessage").html("Error");
}
});
}
function renderChart(data, labels, server) {
var ctx = document.getElementById(server)
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels.split(','),
datasets: [
{
label: 'curr_con',
data: data[0].split(','),
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
},
{
label: 'curr_ssl_con',
data: data[1].split(','),
borderColor: 'rgba(54, 162, 235, 1)',
backgroundColor: 'rgba(54, 162, 235, 0.2)',
},
{
label: 'sess_rate',
data: data[2].split(','),
borderColor: 'rgba(255, 206, 86, 1)',
backgroundColor: 'rgba(255, 206, 86, 0.2)',
},
{
label: 'max_sess_rate',
data: data[3].split(','),
borderColor: 'rgba(192, 192, 192, 1)',
backgroundColor: 'rgba(192, 192, 192, 0.2)',
}
]
},
options: {
title: {
display: true,
text: data[4],
fontSize: 20,
padding: 0,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
legend: {
display: true,
labels: {
fontColor: 'rgb(255, 99, 132)'
},
}
}
});
}
$("#secIntervals").css("display", "none");
function callIframe(url, callback) {
$('#metrics_iframe').html('<iframe id="metrics" style="width:100%;height:100%;" />');
$('iframe#metrics').attr('src', url);
$('iframe#metrics').load(function() {
callback(this);
});
}
function loadMetrics() {
$.get( "options.py?table_metrics=1&token="+$('#token').val(), function( data ) {
$( "#table_metrics" ).html( data );
});
}

View File

@ -546,7 +546,7 @@ $( function() {
$( "#tabs" ).tabs();
$( "select" ).selectmenu();
//var tooltips = $( "[title]" ).tooltip();
// var tooltips = $( "[title]" ).tooltip();
$( "input[type=submit], button" ).button();
$( "input[type=checkbox]" ).checkboxradio();
$( ".controlgroup" ).controlgroup();
@ -563,8 +563,8 @@ $( function() {
});
$( "#show_menu" ).click(function() {
$(".top-menu").show( "drop", "fast" );
$(".container").css("max-width", "91%");
$(".footer").css("max-width", "91%");
$(".container").css("max-width", "100%");
$(".footer").css("max-width", "100%");
$(".container").css("margin-left", "207px");
$(".footer").css("margin-left", "207px");
$(".show_menu").hide();
@ -575,7 +575,7 @@ $( function() {
var hideMenu = Cookies.get('hide_menu');
if (hideMenu == "show") {
$(".top-menu").show( "drop", "fast" );
$(".container").css("max-width", "91%");
$(".container").css("max-width", "100%");
$(".container").css("margin-left", "207px");
}
if (hideMenu == "hide") {
@ -818,7 +818,8 @@ function updateOptions(id) {
url: "sql.py",
data: {
updateoption: $('#option-body-'+id).val(),
id: id
id: id,
token: $('#token').val()
},
type: "GET",
success: function( data ) {
@ -863,6 +864,7 @@ function removeOption(id) {
url: "sql.py",
data: {
optiondel: id,
token: $('#token').val()
},
type: "GET",
success: function( data ) {