0
0
Fork 0
mirror of https://github.com/alerta/alerta.git synced 2025-02-19 03:33:51 +00:00
alerta_alerta/alerta/management/views.py

229 lines
7.5 KiB
Python
Raw Permalink Normal View History

2013-04-09 15:56:39 +00:00
import datetime
import os
2017-09-01 22:22:59 +00:00
import time
2013-04-03 16:24:40 +00:00
from flask import (Response, current_app, g, jsonify, render_template, request,
2018-09-15 22:07:50 +00:00
url_for)
from flask_cors import cross_origin
2014-06-15 00:47:26 +00:00
2017-09-01 22:22:59 +00:00
from alerta.app import db
from alerta.auth.decorators import permission
from alerta.exceptions import ApiError, RejectException
from alerta.models.alert import Alert
2018-11-08 23:34:32 +00:00
from alerta.models.enums import Scope
from alerta.models.heartbeat import Heartbeat
2018-09-15 22:07:50 +00:00
from alerta.models.metrics import Counter, Gauge, Timer
from alerta.models.switch import Switch, SwitchState
from alerta.utils.api import process_action
from alerta.utils.audit import write_audit_trail
2014-12-18 22:16:13 +00:00
from alerta.version import __version__
2017-09-01 22:22:59 +00:00
from . import mgmt
2013-04-02 21:14:25 +00:00
2018-09-15 22:07:50 +00:00
try:
from alerta import build # type: ignore
except Exception:
from alerta import dev as build # type: ignore
2013-04-04 12:21:20 +00:00
switches = [
2018-09-15 22:07:50 +00:00
Switch('auto-refresh-allow', 'Alerta console auto-refresh',
'Allow consoles to auto-refresh alerts', SwitchState.ON),
Switch('sender-api-allow', 'API alert submission', 'Allow alerts to be submitted via the API', SwitchState.ON)
2013-04-04 12:21:20 +00:00
]
2014-03-19 20:37:20 +00:00
total_alert_gauge = Gauge('alerts', 'total', 'Total alerts', 'Total number of alerts in the database')
2017-09-01 22:22:59 +00:00
started = time.time() * 1000
2013-04-04 12:21:20 +00:00
2017-09-01 22:22:59 +00:00
@mgmt.route('/management', methods=['OPTIONS', 'GET'])
2015-01-15 15:10:21 +00:00
@cross_origin()
2013-04-02 21:14:25 +00:00
def management():
endpoints = [
2017-09-01 22:22:59 +00:00
url_for('mgmt.manifest'),
url_for('mgmt.properties'),
url_for('mgmt.switchboard'),
url_for('mgmt.good_to_go'),
url_for('mgmt.health_check'),
url_for('mgmt.housekeeping'),
2017-09-01 22:22:59 +00:00
url_for('mgmt.status'),
url_for('mgmt.prometheus_metrics')
2013-04-02 21:14:25 +00:00
]
return render_template('management/index.html', endpoints=endpoints)
2013-04-02 21:14:25 +00:00
2017-09-01 22:22:59 +00:00
@mgmt.route('/management/manifest', methods=['OPTIONS', 'GET'])
2015-01-15 15:10:21 +00:00
@cross_origin()
2018-11-08 23:34:32 +00:00
@permission(Scope.read_management)
2013-04-02 21:14:25 +00:00
def manifest():
2013-04-03 11:52:53 +00:00
manifest = {
'release': __version__,
'build': build.BUILD_NUMBER,
'date': build.BUILD_DATE,
'revision': build.BUILD_VCS_NUMBER
2013-04-03 11:52:53 +00:00
}
2017-09-20 10:57:00 +00:00
return jsonify(manifest)
2013-04-02 21:14:25 +00:00
2017-09-01 22:22:59 +00:00
@mgmt.route('/management/properties', methods=['OPTIONS', 'GET'])
2015-01-15 15:10:21 +00:00
@cross_origin()
2018-11-08 23:34:32 +00:00
@permission(Scope.admin_management)
2013-04-02 21:14:25 +00:00
def properties():
2013-04-03 11:52:53 +00:00
properties = ''
for k, v in request.environ.items():
properties += '{}: {}\n'.format(k, v)
for k, v in os.environ.items():
properties += '{}: {}\n'.format(k, v)
2017-09-01 22:22:59 +00:00
for k, v in current_app.__dict__.items():
2018-09-15 22:07:50 +00:00
properties += '{}: {}\n'.format(k, v)
2013-04-03 11:52:53 +00:00
2017-09-01 22:22:59 +00:00
for k, v in current_app.config.items():
2018-09-15 22:07:50 +00:00
properties += '{}: {}\n'.format(k, v)
2013-04-03 11:52:53 +00:00
return Response(properties, content_type='text/plain')
2013-04-02 21:14:25 +00:00
2017-09-01 22:22:59 +00:00
@mgmt.route('/management/switchboard', methods=['OPTIONS', 'GET', 'POST'])
2015-01-15 15:10:21 +00:00
@cross_origin()
2018-11-08 23:34:32 +00:00
@permission(Scope.admin_management)
2013-04-02 21:14:25 +00:00
def switchboard():
if request.method == 'POST':
for switch in Switch.find_all():
try:
2013-04-04 12:21:20 +00:00
value = request.form[switch.name]
switch.set_state(value)
except KeyError:
pass
2013-04-04 12:21:20 +00:00
return render_template('management/switchboard.html', switches=switches)
else:
switch = request.args.get('switch', None)
if switch:
return render_template('management/switchboard.html',
2017-12-04 22:09:53 +00:00
switches=[Switch.find_by_name(switch)])
else:
2013-04-04 12:21:20 +00:00
return render_template('management/switchboard.html', switches=switches)
2013-04-02 21:14:25 +00:00
2017-09-01 22:22:59 +00:00
@mgmt.route('/management/gtg', methods=['OPTIONS', 'GET'])
@cross_origin()
def good_to_go():
2017-09-01 22:22:59 +00:00
if db.is_alive:
return 'OK'
else:
return 'FAILED', 503
2017-09-01 22:22:59 +00:00
@mgmt.route('/management/healthcheck', methods=['OPTIONS', 'GET'])
2015-01-15 15:10:21 +00:00
@cross_origin()
2013-04-03 11:52:53 +00:00
def health_check():
2013-04-02 21:14:25 +00:00
try:
2017-09-01 22:22:59 +00:00
heartbeats = Heartbeat.find_all()
2013-04-09 15:56:39 +00:00
for heartbeat in heartbeats:
2014-04-02 19:06:00 +00:00
delta = datetime.datetime.utcnow() - heartbeat.receive_time
2017-09-01 22:22:59 +00:00
threshold = int(heartbeat.timeout) * 4
if delta.seconds > threshold:
2017-09-01 22:22:59 +00:00
return 'HEARTBEAT_STALE: %s' % heartbeat.origin, 503
2013-04-09 15:56:39 +00:00
2014-04-02 19:06:00 +00:00
except Exception as e:
return 'HEALTH_CHECK_FAILED: %s' % e, 503
2013-04-02 21:14:25 +00:00
return 'OK'
@mgmt.route('/management/housekeeping', methods=['OPTIONS', 'GET', 'POST'])
@cross_origin()
2018-11-08 23:34:32 +00:00
@permission(Scope.admin_management)
def housekeeping():
expired_threshold = request.args.get('expired', current_app.config['DEFAULT_EXPIRED_DELETE_HRS'], type='int')
info_threshold = request.args.get('info', current_app.config['DEFAULT_INFO_DELETE_HRS'], type='int')
has_expired, has_timedout = Alert.housekeeping(expired_threshold, info_threshold)
errors = []
for alert in has_expired:
try:
alert, _, text, timeout = process_action(alert, action='expired', text='', timeout=current_app.config['ALERT_TIMEOUT'])
alert = alert.from_expired(text, timeout)
except RejectException as e:
write_audit_trail.send(current_app._get_current_object(), event='alert-expire-rejected', message=alert.text,
user=g.login, customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert',
request=request)
errors.append(str(e))
continue
except Exception as e:
raise ApiError(str(e), 500)
write_audit_trail.send(current_app._get_current_object(), event='alert-expired', message=text, user=g.login,
customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert', request=request)
for alert in has_timedout:
try:
alert, _, text, timeout = process_action(alert, action='timeout', text='', timeout=current_app.config['ALERT_TIMEOUT'])
alert = alert.from_timeout(text, timeout)
except RejectException as e:
write_audit_trail.send(current_app._get_current_object(), event='alert-timeout-rejected', message=alert.text,
user=g.login, customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert',
request=request)
errors.append(str(e))
continue
except Exception as e:
raise ApiError(str(e), 500)
write_audit_trail.send(current_app._get_current_object(), event='alert-timeout', message=text, user=g.login,
customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert', request=request)
if errors:
raise ApiError('housekeeping failed', 500, errors=errors)
else:
return jsonify(
status='ok',
expired=[a.id for a in has_expired],
timedout=[a.id for a in has_timedout],
count=len(has_expired) + len(has_timedout)
)
2017-09-01 22:22:59 +00:00
@mgmt.route('/management/status', methods=['OPTIONS', 'GET'])
2015-01-15 15:10:21 +00:00
@cross_origin()
2018-11-08 23:34:32 +00:00
@permission(Scope.read_management)
2013-04-02 21:14:25 +00:00
def status():
2017-09-01 22:22:59 +00:00
now = int(time.time() * 1000)
total_alert_gauge.set(Alert.get_count())
2017-09-01 22:22:59 +00:00
metrics = Gauge.find_all()
metrics.extend(Counter.find_all())
metrics.extend(Timer.find_all())
metrics.extend(Switch.find_all())
return jsonify(application='alerta', version=__version__, time=now, uptime=int(now - started),
metrics=[metric.serialize() for metric in metrics])
2017-09-01 22:22:59 +00:00
@mgmt.route('/management/metrics', methods=['OPTIONS', 'GET'])
@cross_origin()
2018-11-08 23:34:32 +00:00
@permission(Scope.read_management)
def prometheus_metrics():
2017-09-01 22:22:59 +00:00
total_alert_gauge.set(Alert.get_count())
output = Gauge.find_all()
output += Counter.find_all()
output += Timer.find_all()
return Response(
[o.serialize(format='prometheus') for o in output],
content_type='text/plain; version=0.0.4; charset=utf-8'
)