2019-01-16 14:11:03 +00:00
|
|
|
from functools import wraps
|
2021-03-10 13:55:06 +00:00
|
|
|
|
|
|
|
|
import requests
|
2019-01-16 14:11:03 +00:00
|
|
|
from flask import current_app
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def cronitor(task_name):
|
|
|
|
|
def decorator(func):
|
|
|
|
|
def ping_cronitor(command):
|
2023-08-29 14:54:30 -07:00
|
|
|
if not current_app.config["CRONITOR_ENABLED"]:
|
2019-01-16 14:11:03 +00:00
|
|
|
return
|
|
|
|
|
|
2021-11-16 17:33:36 +00:00
|
|
|
# it's useful to have a log that a periodic task has started in case it
|
|
|
|
|
# get stuck without generating any other logs - we know it got this far
|
2023-08-29 14:54:30 -07:00
|
|
|
current_app.logger.info(f"Pinging Cronitor for Celery task {task_name}")
|
2021-11-16 17:33:36 +00:00
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
task_slug = current_app.config["CRONITOR_KEYS"].get(task_name)
|
2019-01-16 14:11:03 +00:00
|
|
|
if not task_slug:
|
|
|
|
|
current_app.logger.error(
|
2023-08-29 14:54:30 -07:00
|
|
|
"Cronitor enabled but task_name {} not found in environment".format(
|
|
|
|
|
task_name
|
|
|
|
|
)
|
2019-01-16 14:11:03 +00:00
|
|
|
)
|
2019-01-18 15:29:04 +00:00
|
|
|
return
|
2019-01-16 14:11:03 +00:00
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
if command not in {"run", "complete", "fail"}:
|
|
|
|
|
raise ValueError(
|
|
|
|
|
"command {} not a valid cronitor command".format(command)
|
|
|
|
|
)
|
2019-01-16 14:11:03 +00:00
|
|
|
|
2019-01-18 15:29:04 +00:00
|
|
|
try:
|
|
|
|
|
resp = requests.get(
|
2023-08-29 14:54:30 -07:00
|
|
|
"https://cronitor.link/{}/{}".format(task_slug, command),
|
2019-01-18 15:29:04 +00:00
|
|
|
# cronitor limits msg to 1000 characters
|
|
|
|
|
params={
|
2023-08-29 14:54:30 -07:00
|
|
|
"host": current_app.config["API_HOST_NAME"],
|
|
|
|
|
},
|
2025-04-15 11:36:09 -07:00
|
|
|
timeout=30,
|
2019-01-18 15:29:04 +00:00
|
|
|
)
|
|
|
|
|
resp.raise_for_status()
|
|
|
|
|
except requests.RequestException as e:
|
2023-08-29 14:54:30 -07:00
|
|
|
current_app.logger.warning(
|
|
|
|
|
"Cronitor API failed for task {} due to {}".format(
|
|
|
|
|
task_name, repr(e)
|
|
|
|
|
)
|
|
|
|
|
)
|
2019-01-16 14:11:03 +00:00
|
|
|
|
|
|
|
|
@wraps(func)
|
|
|
|
|
def inner_decorator(*args, **kwargs):
|
2023-08-29 14:54:30 -07:00
|
|
|
ping_cronitor("run")
|
|
|
|
|
status = "fail"
|
2019-01-16 14:11:03 +00:00
|
|
|
try:
|
|
|
|
|
ret = func(*args, **kwargs)
|
2023-08-29 14:54:30 -07:00
|
|
|
status = "complete"
|
2019-01-16 14:11:03 +00:00
|
|
|
return ret
|
|
|
|
|
finally:
|
|
|
|
|
ping_cronitor(status)
|
|
|
|
|
|
|
|
|
|
return inner_decorator
|
2023-08-29 14:54:30 -07:00
|
|
|
|
2019-01-16 14:11:03 +00:00
|
|
|
return decorator
|