mirror of https://github.com/Aidaho12/haproxy-wi
parent
2cc270859f
commit
b02cc2fc07
|
@ -361,12 +361,16 @@ if form.getvalue('metrics'):
|
|||
from bokeh.layouts import widgetbox, gridplot
|
||||
from bokeh.models.widgets import Button, RadioButtonGroup, Select
|
||||
import pandas as pd
|
||||
import json
|
||||
import http.cookies
|
||||
|
||||
servers = sql.select_servers_metrics()
|
||||
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
|
||||
user_id = cookie.get('uuid')
|
||||
servers = sql.select_servers_metrics(user_id.value)
|
||||
|
||||
p = {}
|
||||
k = 0
|
||||
for serv in servers:
|
||||
k += 1
|
||||
serv = serv[0]
|
||||
p[serv] = {}
|
||||
metric = sql.select_metrics(serv)
|
||||
|
@ -394,7 +398,7 @@ if form.getvalue('metrics'):
|
|||
x_max = df.index.max() + pd.Timedelta(minutes=1)
|
||||
|
||||
p[serv] = figure(
|
||||
tools="pan,box_zoom,reset,wheel_zoom",
|
||||
tools="pan,box_zoom,reset,xwheel_zoom",
|
||||
title=metric[0][0],
|
||||
x_axis_type="datetime", y_axis_label='Connections',
|
||||
x_range = (x_max.timestamp()*1000-60*100000, x_max.timestamp()*1000)
|
||||
|
@ -404,25 +408,32 @@ if form.getvalue('metrics'):
|
|||
tooltips=[
|
||||
("Connections", "@curr_con"),
|
||||
("SSL connections", "@curr_ssl_con"),
|
||||
("Sessions rate", "@sess_rate"),
|
||||
("Max sessions rate", "@max_sess_rate"),
|
||||
("Sessions rate", "@sess_rate")
|
||||
],
|
||||
mode='mouse'
|
||||
)
|
||||
|
||||
p[serv].ygrid.band_fill_color = "olive"
|
||||
p[serv].ygrid.band_fill_alpha = 0.1
|
||||
|
||||
p[serv].ygrid.band_fill_color = "#f3f8fb"
|
||||
#p[serv].ygrid.band_fill_alpha = 0.1
|
||||
p[serv].y_range.start = 0
|
||||
p[serv].y_range.end = int(df['max_sess_rate'].max()) + 100
|
||||
p[serv].y_range.end = int(df['curr_con'].max()) + 150
|
||||
p[serv].add_tools(hover)
|
||||
p[serv].title.text_font_size = "20px"
|
||||
|
||||
p[serv].line("Date", "curr_con", source=source, alpha=0.5, color='#5cb85c', line_width=2, legend="Conn")
|
||||
p[serv].line("Date", "curr_ssl_con", source=source, alpha=0.5, color="#5d9ceb", line_width=2, legend="SSL con")
|
||||
p[serv].line("Date", "sess_rate", source=source, alpha=0.5, color="#33414e", line_width=2, legend="Sessions")
|
||||
p[serv].line("Date", "max_sess_rate", source=source, alpha=0.5, color="red", line_width=2, legend="Max sess")
|
||||
p[serv].legend.orientation = "horizontal"
|
||||
|
||||
|
||||
if k == 1:
|
||||
p[serv].line("Date", "curr_con", source=source, alpha=0.5, color='#5cb85c', line_width=2, legend="Conn")
|
||||
p[serv].line("Date", "curr_ssl_con", source=source, alpha=0.5, color="#5d9ceb", line_width=2, legend="SSL con")
|
||||
p[serv].line("Date", "sess_rate", source=source, alpha=0.5, color="#33414e", line_width=2, legend="Sessions")
|
||||
#p[serv].line("Date", "max_sess_rate", source=source, alpha=0.5, color="red", line_width=2, legend="Max sess")
|
||||
p[serv].legend.orientation = "horizontal"
|
||||
p[serv].legend.location = "top_left"
|
||||
p[serv].legend.padding = 5
|
||||
else:
|
||||
p[serv].line("Date", "curr_con", source=source, alpha=0.5, color='#5cb85c', line_width=2)
|
||||
p[serv].line("Date", "curr_ssl_con", source=source, alpha=0.5, color="#5d9ceb", line_width=2)
|
||||
p[serv].line("Date", "sess_rate", source=source, alpha=0.5, color="#33414e", line_width=2)
|
||||
#p[serv].line("Date", "max_sess_rate", source=source, alpha=0.5, color="red", line_width=2)
|
||||
|
||||
#select = Select(title="Option:", value="foo", options=["foo", "bar", "baz", "quux"])
|
||||
#show(widgetbox(select, width=300))
|
||||
|
||||
|
@ -430,8 +441,6 @@ if form.getvalue('metrics'):
|
|||
i = 0
|
||||
for key, value in p.items():
|
||||
plots.append(value)
|
||||
|
||||
#plots = plots.sort()
|
||||
|
||||
grid = gridplot(plots, ncols=2, plot_width=800, plot_height=250, toolbar_location = "left", toolbar_options=dict(logo=None))
|
||||
show(grid)
|
26
app/sql.py
26
app/sql.py
|
@ -679,17 +679,33 @@ def select_metrics(serv, **kwargs):
|
|||
cur.close()
|
||||
con.close()
|
||||
|
||||
def select_servers_metrics(**kwargs):
|
||||
def select_servers_metrics(uuid, **kwargs):
|
||||
con, cur = create_db.get_cur()
|
||||
sql = """ select ip from servers where metrics = '1' """
|
||||
sql = """ select * from user where username = '%s' """ % get_user_name_by_uuid(uuid)
|
||||
|
||||
if kwargs.get('disable') == 0:
|
||||
disable = 'or enable = 0'
|
||||
else:
|
||||
disable = ''
|
||||
|
||||
try:
|
||||
cur.execute(sql)
|
||||
except sqltool.Error as e:
|
||||
print('<span class="alert alert-danger" id="error">An error occurred: ' + e + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||
print("An error occurred:", e)
|
||||
else:
|
||||
return cur.fetchall()
|
||||
for group in cur:
|
||||
if group[5] == '1':
|
||||
sql = """ select ip from servers where enable = 1 %s and metrics = '1' """ % (disable)
|
||||
else:
|
||||
sql = """ select ip from servers where groups like '%{group}%' and metrics = '1'""".format(group=group[5])
|
||||
try:
|
||||
cur.execute(sql)
|
||||
except sqltool.Error as e:
|
||||
print("An error occurred:", e.args[0])
|
||||
else:
|
||||
return cur.fetchall()
|
||||
cur.close()
|
||||
con.close()
|
||||
con.close()
|
||||
|
||||
def show_update_telegram(token, page):
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
{% for user in users %}
|
||||
<tr id="user-{{user.0}}">
|
||||
<tr id="user-{{user.0}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="padding10 first-collumn"><input type="text" id="login-{{user.0}}" value="{{user.1}}" class="form-control"></td>
|
||||
<td><input type="password" id="password-{{user.0}}" value="{{user.3}}" class="form-control"></td>
|
||||
<td><input type="text" id="email-{{user.0}}" value="{{user.2}}" class="form-control"></td>
|
||||
|
@ -116,7 +116,7 @@
|
|||
<td></td>
|
||||
</tr>
|
||||
{% for group in groups %}
|
||||
<tr id="group-{{ group.0 }}">
|
||||
<tr id="group-{{ group.0 }}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
{% if group.1 == All %}
|
||||
<td class="padding10 first-collumn">{{ group.1 }}</td>
|
||||
<td>{{ group.2 }}</td>
|
||||
|
@ -172,7 +172,7 @@
|
|||
</tr>
|
||||
|
||||
{% for server in servers %}
|
||||
<tr id="server-{{server.0}}">
|
||||
<tr id="server-{{server.0}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="padding10 first-collumn">
|
||||
<input type="text" id="hostname-{{server.0}}" value="{{server.1}}" class="form-control">
|
||||
</td>
|
||||
|
@ -324,7 +324,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
{% for role in roles %}
|
||||
<tr id="group-{{role.0}}">
|
||||
<tr id="group-{{role.0}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="padding10 first-collumn">{{role.1}}</td>
|
||||
<td>{{role.2}}</td>
|
||||
</tr>
|
||||
|
@ -348,7 +348,7 @@
|
|||
<td></td>
|
||||
</tr>
|
||||
{% for ssh in sshs %}
|
||||
<tr style="width: 50%;" id="ssh-table-{{ssh.0}}">
|
||||
<tr style="width: 50%;" id="ssh-table-{{ssh.0}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="first-collumn">
|
||||
<input type="text" id="ssh_name-{{ssh.0}}" class="form-control" value="{{ssh.1}}" style="margin-bottom: 23px;">
|
||||
</td>
|
||||
|
@ -461,7 +461,7 @@
|
|||
<td></td>
|
||||
</tr>
|
||||
{% for telegram in telegrams %}
|
||||
<tr id="telegram-table-{{telegram.0}}">
|
||||
<tr id="telegram-table-{{telegram.0}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="first-collumn" style="padding-top: 20px;">
|
||||
<input type="text" id="telegram-token-{{telegram.0}}" class="form-control" value="{{telegram.1}}" style="margin-bottom: 23px;">
|
||||
</td>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% for service in service_status %}
|
||||
<tr>
|
||||
<tr class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="padding10 first-collumn">
|
||||
<a href="#{{ service.0 }}" title="Go to {{ service.0 }} status" style="color: #000">{{ service.0 }}</a>
|
||||
</td>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{% for USER in users %}
|
||||
{% set counter = counter + loop.index0 %}
|
||||
{% if counter <= 2 %}
|
||||
<tr>
|
||||
<tr class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="padding10 first-collumn"> {{ USER.1 }}</td>
|
||||
<td class="padding10"> {{ USER.2 }}</td>
|
||||
{% for group in groups %}
|
||||
|
@ -36,7 +36,7 @@
|
|||
<td></td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr style="display: none;" class="show-users">
|
||||
<tr style="display: none;" class="show-users {{ loop.cycle('odd', 'even') }}">
|
||||
<td class="padding10 first-collumn"> {{ USER.1 }}</td>
|
||||
<td class="padding10"> {{ USER.2 }}</td>
|
||||
{% for group in groups %}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
{% set ssh_group = [] %}
|
||||
{% for server in servers %}
|
||||
{% do ssh_group.append(server.3) %}
|
||||
<tr id="server-{{server.0}}">
|
||||
<tr id="server-{{server.0}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="padding10 first-collumn">
|
||||
<input type="text" id="hostname-{{server.0}}" value="{{server.1}}" class="form-control">
|
||||
</td>
|
||||
|
@ -177,7 +177,7 @@
|
|||
</tr>
|
||||
{% for ssh in sshs %}
|
||||
{% if ssh.5|string() == group %}
|
||||
<tr style="width: 50%;" id="ssh-table-{{ssh.0}}">
|
||||
<tr style="width: 50%;" id="ssh-table-{{ssh.0}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="first-collumn">
|
||||
<input type="text" id="ssh_name-{{ssh.0}}" class="form-control" value="{{ssh.1}}" style="margin-bottom: 23px;">
|
||||
<input type="hidden" id="new-ssh-group-add" name="new-ssh-group-add" value="{{ ssh_group }}" >
|
||||
|
@ -275,7 +275,7 @@
|
|||
</tr>
|
||||
{% for telegram in telegrams %}
|
||||
{% if telegram.3|string() == group %}
|
||||
<tr style="width: 50%;" id="telegram-table-{{telegram.0}}">
|
||||
<tr style="width: 50%;" id="telegram-table-{{telegram.0}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="first-collumn" style="padding-top: 20px;">
|
||||
<input type="text" id="telegram-token-{{telegram.0}}" class="form-control" value="{{telegram.1}}" style="margin-bottom: 23px;">
|
||||
</td>
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
import time
|
||||
import argparse
|
||||
import os, sys
|
||||
sys.path.append(os.path.join(sys.path[0], os.path.dirname(os.getcwd())))
|
||||
sys.path.append(os.path.join(sys.path[0], os.getcwd()))
|
||||
import funct
|
||||
import sql
|
||||
import signal
|
||||
|
||||
class GracefulKiller:
|
||||
kill_now = False
|
||||
def __init__(self):
|
||||
signal.signal(signal.SIGINT, self.exit_gracefully)
|
||||
signal.signal(signal.SIGTERM, self.exit_gracefully)
|
||||
|
||||
def exit_gracefully(self,signum, frame):
|
||||
self.kill_now = True
|
||||
|
||||
def main():
|
||||
sql.delete_mentrics()
|
||||
servers = sql.select_servers_metrics()
|
||||
started_workers = get_worker()
|
||||
servers_list = []
|
||||
|
||||
for serv in servers:
|
||||
servers_list.append(serv[0])
|
||||
|
||||
need_kill=list(set(started_workers) - set(servers_list))
|
||||
need_start=list(set(servers_list) - set(started_workers))
|
||||
|
||||
if need_kill:
|
||||
for serv in need_kill:
|
||||
kill_worker(serv)
|
||||
|
||||
if need_start:
|
||||
for serv in need_start:
|
||||
start_worker(serv)
|
||||
|
||||
def start_worker(serv):
|
||||
port = funct.get_config_var('haproxy', 'haproxy_sock_port')
|
||||
cmd = "tools/metrics_worker.py %s --port %s &" % (serv, port)
|
||||
os.system(cmd)
|
||||
funct.logging("localhost", " Masrer started new metrics worker for: "+serv, metrics=1)
|
||||
|
||||
def kill_worker(serv):
|
||||
cmd = "ps ax |grep 'tools/metrics_worker.py %s'|grep -v grep |awk '{print $1}' |xargs kill" % serv
|
||||
output, stderr = funct.subprocess_execute(cmd)
|
||||
funct.logging("localhost", " Masrer killed metrics worker for: "+serv, metrics=1)
|
||||
if stderr:
|
||||
funct.logging("localhost", stderr, metrics=1)
|
||||
|
||||
def kill_all_workers():
|
||||
cmd = "ps ax |grep 'tools/metrics_worker.py' |grep -v grep |awk '{print $1}' |xargs kill"
|
||||
output, stderr = funct.subprocess_execute(cmd)
|
||||
funct.logging("localhost", " Masrer killing all metrics workers", metrics=1)
|
||||
if stderr:
|
||||
funct.logging("localhost", stderr, metrics=1)
|
||||
|
||||
def get_worker():
|
||||
cmd = "ps ax |grep 'tools/metrics_worker.py' |grep -v grep |awk '{print $7}'"
|
||||
output, stderr = funct.subprocess_execute(cmd)
|
||||
if stderr:
|
||||
funct.logging("localhost", stderr, metrics=1)
|
||||
return output
|
||||
|
||||
if __name__ == "__main__":
|
||||
funct.logging("localhost", " Metrics master started", metrics=1)
|
||||
killer = GracefulKiller()
|
||||
|
||||
while True:
|
||||
main()
|
||||
time.sleep(20)
|
||||
|
||||
if killer.kill_now:
|
||||
break
|
||||
|
||||
kill_all_workers()
|
||||
funct.logging("localhost", " Master shutdown", metrics=1)
|
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
from subprocess import check_output, CalledProcessError
|
||||
import time
|
||||
import argparse
|
||||
import os, sys
|
||||
sys.path.append(os.path.join(sys.path[0], os.path.dirname(os.getcwd())))
|
||||
sys.path.append(os.path.join(sys.path[0], os.getcwd()))
|
||||
import sql
|
||||
import signal
|
||||
|
||||
class GracefulKiller:
|
||||
kill_now = False
|
||||
def __init__(self):
|
||||
signal.signal(signal.SIGINT, self.exit_gracefully)
|
||||
signal.signal(signal.SIGTERM, self.exit_gracefully)
|
||||
|
||||
def exit_gracefully(self,signum, frame):
|
||||
self.kill_now = True
|
||||
|
||||
def main(serv, port):
|
||||
port = str(port)
|
||||
firstrun = True
|
||||
currentstat = []
|
||||
readstats = ""
|
||||
killer = GracefulKiller()
|
||||
old_stat_service = ""
|
||||
|
||||
while True:
|
||||
try:
|
||||
cmd = "echo show info | nc "+serv+" "+port+" |grep -e 'Curr\|MaxSessRate:\|SessRate:'|awk '{print $2}'"
|
||||
readstats = subprocess.check_output([cmd], shell=True)
|
||||
except CalledProcessError as e:
|
||||
print("Command error")
|
||||
except OSError as e:
|
||||
print(e)
|
||||
sys.exit()
|
||||
readstats = readstats.decode(encoding='UTF-8')
|
||||
metric = readstats.splitlines()
|
||||
metrics = []
|
||||
for i in range(0,len(metric)):
|
||||
metrics.append(metric[i])
|
||||
|
||||
sql.insert_mentrics(serv, metrics[0], metrics[1], metrics[2], metrics[3])
|
||||
|
||||
time.sleep(30)
|
||||
|
||||
if killer.kill_now:
|
||||
break
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Metrics HAProxy service.', prog='check_haproxy.py', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
|
||||
parser.add_argument('IP', help='Start get metrics from HAProxy service at this ip', nargs='?', type=str)
|
||||
parser.add_argument('--port', help='Start get metrics from HAProxy service at this port', nargs='?', default=1999, type=int)
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.IP is None:
|
||||
parser.print_help()
|
||||
import sys
|
||||
sys.exit()
|
||||
else:
|
||||
try:
|
||||
main(args.IP, args.port)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
|
@ -26,7 +26,9 @@ window.onblur= function() {
|
|||
showOverview();
|
||||
} else if (cur_url[0] == "viewlogs.py") {
|
||||
viewLogs();
|
||||
}
|
||||
} else if (cur_url[0] == "metrics.py") {
|
||||
loadMetrics();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -596,4 +596,7 @@ label {
|
|||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.even {
|
||||
background-color: #f3f8fb;
|
||||
}
|
Loading…
Reference in New Issue