From defd05f2f7ef262a46d27784bf6e8f23c0ce1667 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Mon, 18 Sep 2023 09:42:01 -0400 Subject: [PATCH] add reporting for Healthchecks --- yacron/config.py | 8 ++++++++ yacron/job.py | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/yacron/config.py b/yacron/config.py index 1806133..127f3a5 100644 --- a/yacron/config.py +++ b/yacron/config.py @@ -87,6 +87,9 @@ class ConfigError(Exception): "shell": "/bin/sh", "command": None, }, + "healthchecks": { + "ping_url": None, + }, } @@ -173,6 +176,11 @@ class ConfigError(Exception): "command": Str() | Seq(Str()), } ), + Opt("healthchecks"): Map( + { + "ping_url": Str(), + } + ), } ) diff --git a/yacron/job.py b/yacron/job.py index 5ea7ea7..c6a2621 100644 --- a/yacron/job.py +++ b/yacron/job.py @@ -10,6 +10,7 @@ from typing import Any, Dict, List, Optional, Tuple import subprocess +import aiohttp import sentry_sdk import sentry_sdk.utils @@ -161,6 +162,31 @@ async def report( body, level=config.get("level", "error") ) +class HealthchecksReporter(Reporter): + async def report( + self, success: bool, job: 'RunningJob', config: Dict[str, Any] + ) -> None: + config = config['healthchecks'] + # Exit early if not successful since Healthchecks only receives positive events. + if not success or not config['ping_url']: + return + + url = config['ping_url'] + bad_req = False + try: + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + txt = await resp.text() + if txt != 'OK': + logger.debug("Got unexpected response from %s: %r", url, txt) + bad_req = True + except Exception: + bad_req = True + logger.exception("Error GETing %s", config['ping_url']) + + if bad_req: + return + class MailReporter(Reporter): async def report( @@ -327,6 +353,7 @@ class RunningJob: SentryReporter(), MailReporter(), ShellReporter(), + HealthchecksReporter(), ] # type: List[Reporter] def __init__(