diff --git a/alertmanager_status.py b/alertmanager_status.py index be27b67e655c0bbabba47a15658db283441f28cc..aeb850c9b21a0063164d358b6a4fe6027d18944b 100755 --- a/alertmanager_status.py +++ b/alertmanager_status.py @@ -13,10 +13,9 @@ from query_alertmanager import get_alerts def show_alerts(opts): """Show alerts.""" - alerts = get_alerts(url=opts["url"], - port=opts["port"], - user=opts["user"], - password=opts["password"]) + alerts = get_alerts( + url=opts["url"], port=opts["port"], user=opts["user"], password=opts["password"] + ) # Construct waybar output # https://github.com/Alexays/Waybar/wiki/Module:-Custom#return-type @@ -24,42 +23,41 @@ def show_alerts(opts): # "class": "$class", "percentage": $percentage }. # This means the output should also be on a single line output = {} - output["text"] = alerts['summary'] - if alerts['summary'] == "Cant connect": + output["text"] = alerts["summary"] + if alerts["summary"] == "Cant connect": output["alt"] = "error" output["tooltip"] = "Some error occurred." else: if alerts["count"] > 0: output["alt"] = "firing" - output["tooltip"] = '\n'.join(alerts['alerts']) + output["tooltip"] = "\n".join(alerts["alerts"]) else: output["alt"] = "snafu" output["tooltip"] = "Situation normal, all fucked up 😃" print(json.dumps(output)) -@plac.opt('configpath', "Path to alertmanager config", type=Path) -@plac.opt('mode', "Mode", type=str, choices=['waybar', 'indicator']) +@plac.opt("configpath", "Path to alertmanager config", type=Path) +@plac.opt("mode", "Mode", type=str, choices=["waybar", "indicator"]) # plac.flg('debug', "Enable debug mode") -def main(configpath='~/.config/alertmanager_status/config.yml', - mode="wayland"): +def main(configpath="~/.config/alertmanager_status/config.yml", mode="wayland"): """Main function.""" # Load config with open(Path.expanduser(configpath), encoding="UTF8") as config_file: # type:ignore opts_raw = yaml.load(config_file, Loader=yaml.FullLoader) opts = {} - opts["url"] = opts_raw.get('url') - opts["port"] = opts_raw.get('port', 443) - opts["user"] = opts_raw.get('user', 'admin') - opts["password"] = opts_raw.get('password') + opts["url"] = opts_raw.get("url") + opts["port"] = opts_raw.get("port", 443) + opts["user"] = opts_raw.get("user", "admin") + opts["password"] = opts_raw.get("password") opts["icon_red"] = os.path.abspath("./prometheus.svg") opts["icon_green"] = os.path.abspath("./prometheus-green.svg") if mode == "wayland": show_alerts(opts) # if mode == "indicator": - # Indicator() + # Indicator() if __name__ == "__main__": diff --git a/query_alertmanager.py b/query_alertmanager.py index 63fb710932f59f285d845ecef9f4593f8b16ee3e..3cd2673549ec31424c62607f956367e24377f909 100755 --- a/query_alertmanager.py +++ b/query_alertmanager.py @@ -10,30 +10,38 @@ Usage: import json import plac import requests -from alertmanager import AlertManager +import traceback +# import pprint -def get_alerts(url, password, port=443, user='admin'): - req = requests.Session() - req.auth = (user, password) - AM = AlertManager(host=url, port=port, req_obj=req) +def get_alerts(url, password, port=443, user="admin"): + """Query alerts. + + https://koumoul.com/openapi-viewer/?url=https://raw.githubusercontent.com/prometheus/alertmanager/master/api/v2/openapi.yaml&proxy=false + """ + api_url = f"{url}/api/v2/alerts" + query = {"silenced": "false"} + req = requests.get(api_url, auth=(user, password), params=query) + alerts_json = req.json() count = 0 alerts = [] state = "unknown" try: - alerts_raw = AM.get_alerts() - for alert in alerts_raw: - name = alert['labels']['alertname'] - severity = alert['labels']['severity'] - instance = alert['labels']['instance'] - alert_state = alert['status']['state'] - release_name = alert['labels']['release_name'] + for alert in alerts_json: + # pp = pprint.PrettyPrinter(indent=2) + # pp.pprint(alert) + + name = alert["labels"]["alertname"] + severity = alert["labels"]["severity"] + instance = alert["labels"].get("instance", "") + alert_state = alert["status"]["state"] + release_name = alert["labels"].get("release_name", "") if severity != "none" and alert_state != "suppressed": count += 1 - alert_text = f'{name}: {instance}, {release_name} ({severity})' + alert_text = f"{name}: {instance}, {release_name} ({severity})" alerts.append(alert_text) if count > 2: @@ -43,28 +51,26 @@ def get_alerts(url, password, port=443, user='admin'): elif count == 0: state = "ok" - summary = f'{count} alerts' - except: + summary = f"{count} alerts" + except Exception as e: + print(f"The error is: {e}") + traceback.print_exc() summary = "Cant connect" state = "warning" - return_data = { - 'summary': summary, - 'alerts': alerts, - 'state': state, - 'count': count} + return_data = {"summary": summary, "alerts": alerts, "state": state, "count": count} return return_data -@plac.pos('url', "URL of alertmanager instance", type=str) -@plac.pos('password', "Password", type=str) -@plac.opt('port', "Port of alertmanager instance", type=int, abbrev='P') -@plac.opt('user', "User name", type=str) -def main(url, password, port=443, user='admin'): +@plac.pos("url", "URL of alertmanager instance", type=str) +@plac.pos("password", "Password", type=str) +@plac.opt("port", "Port of alertmanager instance", type=int, abbrev="P") +@plac.opt("user", "User name", type=str) +def main(url, password, port=443, user="admin"): """Main function.""" alerts = get_alerts(url=url, password=password, port=port, user=user) print(json.dumps(alerts)) -if __name__ == '__main__': +if __name__ == "__main__": plac.call(main) diff --git a/requirements.in b/requirements.in index eabbd4e729ae92f28fe4eca57eaf3b7836b5c844..704c90c72fa385b5a14c34264f971ee5d7942465 100644 --- a/requirements.in +++ b/requirements.in @@ -1,5 +1,11 @@ -plac -pylertalertmanager -# Only needed for indicator.py +# https://pypi.org/project/plac/#history +plac==1.4.3 +# https://pypi.org/project/PyYAML/#history +pyyaml==6.0.1 + +#Only needed for indicator.py # pygobject -pyyaml + +# Dev deps +neovim +pip-tools diff --git a/requirements.txt b/requirements.txt index 62074f387f0d493c4f352864be5af14934fe5095..1c8d7a7bf987463ef4fa6a30cb6d7e8e13c5d869 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,54 +4,33 @@ # # pip-compile # -certifi==2024.2.2 - # via requests -charset-normalizer==3.3.2 - # via requests -dateparser==1.2.0 - # via maya -humanize==4.9.0 - # via maya -idna==3.6 - # via requests -maya==0.6.1 - # via pylertalertmanager -pendulum==3.0.0 - # via maya -plac==1.4.3 +build==1.1.1 + # via pip-tools +click==8.1.7 + # via pip-tools +greenlet==3.0.3 + # via pynvim +msgpack==1.0.8 + # via pynvim +neovim==0.3.1 # via -r requirements.in -pylertalertmanager==0.1.1 +packaging==23.2 + # via build +pip-tools==7.4.1 # via -r requirements.in -python-box==7.1.1 - # via pylertalertmanager -python-dateutil==2.8.2 - # via - # dateparser - # pendulum - # snaptime - # time-machine -pytz==2024.1 +plac==1.4.3 + # via -r requirements.in +pynvim==0.5.0 + # via neovim +pyproject-hooks==1.0.0 # via - # dateparser - # maya - # snaptime + # build + # pip-tools pyyaml==6.0.1 # via -r requirements.in -regex==2023.12.25 - # via dateparser -requests==2.31.0 - # via pylertalertmanager -six==1.16.0 - # via python-dateutil -snaptime==0.2.4 - # via maya -time-machine==2.13.0 - # via pendulum -tzdata==2024.1 - # via pendulum -tzlocal==5.2 - # via - # dateparser - # maya -urllib3==2.2.1 - # via requests +wheel==0.42.0 + # via pip-tools + +# The following packages are considered to be unsafe in a requirements file: +# pip +# setuptools