add cli to list/clear failures and fix if-alerted alerting
This commit is contained in:
+15
-1
@@ -2,7 +2,7 @@ import datetime
|
|||||||
import os
|
import os
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
def register_success(name, db):
|
def clear_failure(name, db):
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute('''
|
cur.execute('''
|
||||||
DELETE FROM alert
|
DELETE FROM alert
|
||||||
@@ -86,6 +86,20 @@ def get_failures(name, db):
|
|||||||
failures.sort(key=lambda x: x['timestamp'])
|
failures.sort(key=lambda x: x['timestamp'])
|
||||||
return failures
|
return failures
|
||||||
|
|
||||||
|
def get_services(db):
|
||||||
|
cur = db.cursor()
|
||||||
|
cur.execute('''SELECT
|
||||||
|
service.name, COUNT(*)
|
||||||
|
FROM service
|
||||||
|
JOIN failure ON
|
||||||
|
failure.service=service.id
|
||||||
|
GROUP BY
|
||||||
|
service.name;
|
||||||
|
''')
|
||||||
|
db.commit()
|
||||||
|
ret = {name: failures for (name, failures) in cur.fetchall()}
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def init(path):
|
def init(path):
|
||||||
con = sqlite3.connect(path, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
|
con = sqlite3.connect(path, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
|
||||||
|
|||||||
+53
-3
@@ -1,4 +1,4 @@
|
|||||||
|
import argparse
|
||||||
import configparser
|
import configparser
|
||||||
import datetime
|
import datetime
|
||||||
import importlib
|
import importlib
|
||||||
@@ -37,11 +37,12 @@ def register_exit(config, db):
|
|||||||
if os.environ['MONITOR_SERVICE_RESULT'] == 'success':
|
if os.environ['MONITOR_SERVICE_RESULT'] == 'success':
|
||||||
# exit with success status
|
# exit with success status
|
||||||
failures = sysalert.db.get_failures(service_name, db)
|
failures = sysalert.db.get_failures(service_name, db)
|
||||||
sysalert.db.register_success(service_name, db)
|
sysalert.db.clear_failure(service_name, db)
|
||||||
try:
|
try:
|
||||||
do_alert = config.getboolean(section_name, 'recovery_alert')
|
do_alert = config.getboolean(section_name, 'recovery_alert')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if config.get(section_name, 'recovery_alert') == 'if-alerted' and failures:
|
if config.get(section_name, 'recovery_alert') == 'if-alerted' and \
|
||||||
|
any([f['alert_method'] for f in failures]):
|
||||||
do_alert = True
|
do_alert = True
|
||||||
else:
|
else:
|
||||||
do_alert = False
|
do_alert = False
|
||||||
@@ -75,6 +76,27 @@ def register_exit(config, db):
|
|||||||
alert.failure(service_name, failures, alert_config)
|
alert.failure(service_name, failures, alert_config)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def cli_args():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Manage active sysalerts',
|
||||||
|
epilog='''Note that when called from systemd this argument parser
|
||||||
|
is not used. Use the provided sysalert-* services and see
|
||||||
|
documentation for details.''')
|
||||||
|
parser.add_argument('--service', '-s',
|
||||||
|
help='Only operate on specific service')
|
||||||
|
subparsers = parser.add_subparsers()
|
||||||
|
|
||||||
|
parser_list = subparsers.add_parser('list')
|
||||||
|
parser_list.set_defaults(cmd='list')
|
||||||
|
|
||||||
|
parser_clear = subparsers.add_parser('clear')
|
||||||
|
parser_clear.set_defaults(cmd='clear')
|
||||||
|
parser_clear.add_argument('--force', '-f',
|
||||||
|
action='store_true',
|
||||||
|
help='''Force clear for all services if service is
|
||||||
|
not specified''')
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
def cli():
|
def cli():
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@@ -85,9 +107,37 @@ def cli():
|
|||||||
if _test_env():
|
if _test_env():
|
||||||
# invoked by systemd
|
# invoked by systemd
|
||||||
ret = register_exit(config, db)
|
ret = register_exit(config, db)
|
||||||
|
else:
|
||||||
|
args = cli_args()
|
||||||
|
if args.service and not args.service.endswith('.service'):
|
||||||
|
args.service = f'{args.service}.service'
|
||||||
|
|
||||||
|
if args.cmd == 'list':
|
||||||
|
cli_list(args, db)
|
||||||
|
elif args.cmd == 'clear':
|
||||||
|
cli_clear(args, db)
|
||||||
|
|
||||||
sysalert.db.close(db)
|
sysalert.db.close(db)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def cli_list(args, db):
|
||||||
|
for service, failures in sysalert.db.get_services(db).items():
|
||||||
|
if args.service and args.service == service:
|
||||||
|
print(f'{service}: {failures} failures')
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def cli_clear(args, db):
|
||||||
|
if not args.service and not args.force:
|
||||||
|
print(f'No service specified, use "--force" to clear all services', sys.stderr)
|
||||||
|
return 1
|
||||||
|
if args.service:
|
||||||
|
sysalert.db.clear_failure(args.service, db)
|
||||||
|
print(f'Cleared failures for {args.service}')
|
||||||
|
else:
|
||||||
|
for service, failures in sysalert.db.get_services(db).items():
|
||||||
|
sysalert.db.clear_failure(service, db)
|
||||||
|
print(f'Cleared all failures')
|
||||||
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(cli())
|
sys.exit(cli())
|
||||||
|
|||||||
Reference in New Issue
Block a user