v8.1.2: Refactor metric insertion and selection logic

Consolidated multiple metric insertion and deletion functions into more generic and reusable functions using dictionaries and typing literals. This refactoring reduces code duplication and improves maintainability. Additionally, flask route functions have been updated to use type validation, ensuring stronger typing and input verification.
pull/403/head
Aidaho 2024-12-01 14:43:39 +03:00
parent ddd9a1b92d
commit 6cfaf90743
2 changed files with 45 additions and 210 deletions

View File

@ -1,157 +1,37 @@
from typing import Literal
from app.modules.db.db_model import connect, mysql_enable, Metrics, MetricsHttpStatus, Server, NginxMetrics, ApacheMetrics, WafMetrics from app.modules.db.db_model import connect, mysql_enable, Metrics, MetricsHttpStatus, Server, NginxMetrics, ApacheMetrics, WafMetrics
from app.modules.db.common import out_error from app.modules.db.common import out_error
import app.modules.roxy_wi_tools as roxy_wi_tools import app.modules.roxy_wi_tools as roxy_wi_tools
MODELS = {
'haproxy': Metrics,
'nginx': NginxMetrics,
'apache': ApacheMetrics,
'http': MetricsHttpStatus,
'waf': WafMetrics
}
def insert_metrics(serv, curr_con, cur_ssl_con, sess_rate, max_sess_rate):
def insert_service_metrics(service: Literal['haproxy', 'nginx', 'apache', 'waf', 'http'], **kwargs):
get_date = roxy_wi_tools.GetDate() get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular') cur_date = get_date.return_date('regular')
kwargs['date'] = cur_date
model = MODELS[service]
try: try:
Metrics.insert( model.insert(**kwargs).execute()
serv=serv, curr_con=curr_con, cur_ssl_con=cur_ssl_con, sess_rate=sess_rate, max_sess_rate=max_sess_rate,
date=cur_date
).execute()
except Exception as e: except Exception as e:
out_error(e) out_error(e)
else:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def insert_metrics_http(serv, http_2xx, http_3xx, http_4xx, http_5xx): def delete_service_metrics(service: Literal['haproxy', 'http', 'waf', 'nginx', 'apache']) -> None:
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
MetricsHttpStatus.insert(
serv=serv, ok_ans=http_2xx, redir_ans=http_3xx, not_found_ans=http_4xx, err_ans=http_5xx,
date=cur_date
).execute()
except Exception as e:
out_error(e)
else:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def insert_nginx_metrics(serv, connection):
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
NginxMetrics.insert(serv=serv, conn=connection, date=cur_date).execute()
except Exception as e:
out_error(e)
else:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def insert_apache_metrics(serv, connection):
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
ApacheMetrics.insert(serv=serv, conn=connection, date=cur_date).execute()
except Exception as e:
out_error(e)
else:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def insert_waf_metrics(serv, connection):
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
WafMetrics.insert(serv=serv, conn=connection, date=cur_date).execute()
except Exception as e:
out_error(e)
finally:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def delete_waf_metrics():
get_date = roxy_wi_tools.GetDate() get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3) cur_date = get_date.return_date('regular', timedelta_minus=3)
query = WafMetrics.delete().where(WafMetrics.date < cur_date) model = MODELS[service]
try: try:
query.execute() model.delete().where(model.date < cur_date).execute()
except Exception as e: except Exception as e:
out_error(e) out_error(e)
finally:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def delete_metrics():
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = Metrics.delete().where(Metrics.date < cur_date)
try:
query.execute()
except Exception as e:
out_error(e)
finally:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def delete_http_metrics():
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = MetricsHttpStatus.delete().where(MetricsHttpStatus.date < cur_date)
try:
query.execute()
except Exception as e:
out_error(e)
finally:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def delete_nginx_metrics():
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = NginxMetrics.delete().where(NginxMetrics.date < cur_date)
try:
query.execute()
except Exception as e:
out_error(e)
finally:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def delete_apache_metrics():
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = ApacheMetrics.delete().where(ApacheMetrics.date < cur_date)
try:
query.execute()
except Exception as e:
out_error(e)
finally:
conn = connect()
if type(conn) is not str:
if not conn.is_closed():
conn.close()
def select_metrics(serv, service, **kwargs): def select_metrics(serv, service, **kwargs):
@ -206,72 +86,28 @@ def select_metrics(serv, service, **kwargs):
return cursor.fetchall() return cursor.fetchall()
def select_servers_metrics_for_master(**kwargs): def select_servers_metrics_for_master(group_id: int):
if kwargs.get('group') != 1:
query = Server.select(Server.ip).where(
((Server.haproxy_metrics == 1) | (Server.nginx_metrics == 1) | (Server.apache_metrics == 1))
& (Server.group_id == kwargs.get('group'))
)
else:
query = Server.select(Server.ip).where(
(Server.haproxy_metrics == 1)
| (Server.nginx_metrics == 1)
| (Server.apache_metrics == 1)
)
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def select_haproxy_servers_metrics_for_master():
query = Server.select(Server.ip).where(Server.haproxy_metrics == 1)
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def select_nginx_servers_metrics_for_master():
query = Server.select(Server.ip).where((Server.nginx_metrics == 1) & (Server.nginx == 1))
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def select_apache_servers_metrics_for_master():
query = Server.select(Server.ip).where( query = Server.select(Server.ip).where(
(Server.apache_metrics == 1) ((Server.haproxy_metrics == 1) | (Server.nginx_metrics == 1) | (Server.apache_metrics == 1))
& (Server.apache == 1) & (Server.group_id == group_id)
) )
try: try:
query_res = query.execute() return query.execute()
except Exception as e: except Exception as e:
out_error(e) out_error(e)
else:
return query_res
def select_servers_metrics(group_id): def select_metrics_enabled(service: Literal['haproxy', 'nginx', 'apache']):
if group_id == 1: query_where = {
query = Server.select(Server.ip).where((Server.enabled == 1) & (Server.haproxy_metrics == 1)) 'haproxy': ((Server.haproxy_metrics == 1) & (Server.haproxy == 1)),
else: 'nginx': ((Server.nginx_metrics == 1) & (Server.nginx == 1)),
query = Server.select(Server.ip).where( 'apache': ((Server.apache_metrics == 1) & (Server.apache == 1)),
(Server.enabled == 1) & (Server.group_id == group_id) & (Server.haproxy_metrics == 1)) }
try: try:
query_res = query.execute() return Server.select(Server.ip).where(query_where[service] & (Server.enabled == 1)).execute()
except Exception as e: except Exception as e:
out_error(e) out_error(e)
else:
return query_res
def select_table_metrics(group_id): def select_table_metrics(group_id):

View File

@ -1,9 +1,12 @@
import json import json
import time import time
from typing import Union, Literal
import distro import distro
from flask import render_template, request, jsonify, g, Response, stream_with_context from flask import render_template, request, jsonify, g, Response, stream_with_context
from flask_jwt_extended import jwt_required from flask_jwt_extended import jwt_required
from flask_pydantic import validate
from pydantic import IPvAnyAddress
from app.routes.metric import bp from app.routes.metric import bp
import app.modules.db.server as server_sql import app.modules.db.server as server_sql
@ -14,6 +17,7 @@ import app.modules.common.common as common
import app.modules.server.server as server_mod import app.modules.server.server as server_mod
import app.modules.roxywi.metrics as metric import app.modules.roxywi.metrics as metric
import app.modules.roxywi.common as roxywi_common import app.modules.roxywi.common as roxywi_common
from app.modules.roxywi.class_models import DomainName
@bp.before_request @bp.before_request
@ -44,13 +48,7 @@ def metrics(service):
servers = '' servers = ''
else: else:
services = '1' services = '1'
if service == 'nginx': servers = metric_sql.select_metrics_enabled(service)
servers = metric_sql.select_nginx_servers_metrics_for_master()
elif service == 'apache':
servers = metric_sql.select_apache_servers_metrics_for_master()
else:
group_id = roxywi_common.get_user_group(id=1)
servers = metric_sql.select_servers_metrics(group_id)
else: else:
servers = '' servers = ''
except Exception as e: except Exception as e:
@ -99,8 +97,9 @@ def table_metrics(service):
@bp.post('/<service>/<server_ip>') @bp.post('/<service>/<server_ip>')
def show_metric(service, server_ip): @validate()
server_ip = common.is_ip_or_dns(server_ip) def show_metric(service: str, server_ip: Union[IPvAnyAddress, DomainName]):
server_ip = str(server_ip)
server = server_sql.get_server_by_ip(server_ip) server = server_sql.get_server_by_ip(server_ip)
time_range = common.checkAjaxInput(request.form.get('time_range')) time_range = common.checkAjaxInput(request.form.get('time_range'))
@ -114,20 +113,20 @@ def show_metric(service, server_ip):
@bp.post('/<service>/<server_ip>/http') @bp.post('/<service>/<server_ip>/http')
@check_services @check_services
def show_http_metric(service, server_ip): @validate()
server_ip = common.is_ip_or_dns(server_ip) def show_http_metric(service: Literal['haproxy'], server_ip: Union[IPvAnyAddress, DomainName]):
server = server_sql.get_server_by_ip(server_ip) server = server_sql.get_server_by_ip(str(server_ip))
time_range = common.checkAjaxInput(request.form.get('time_range')) time_range = common.checkAjaxInput(request.form.get('time_range'))
if service == 'haproxy': return jsonify(metric.haproxy_http_metrics(server.ip, server.hostname, time_range))
return jsonify(metric.haproxy_http_metrics(server_ip, server.hostname, time_range))
return 'error: Wrong service'
@bp.route('/<service>/<server_ip>/<is_http>/chart-stream') @bp.route('/<service>/<server_ip>/<is_http>/chart-stream')
@check_services @check_services
def chart_data(service, server_ip, is_http): @validate()
def chart_data(service: str, server_ip: Union[IPvAnyAddress, DomainName], is_http: int):
server_ip = str(server_ip)
def get_chart_data(): def get_chart_data():
while True: while True:
json_metric = {} json_metric = {}