diff --git a/mftp-doctor/env.example.py b/mftp-doctor/env.example.py index 457ab05..39640ea 100644 --- a/mftp-doctor/env.example.py +++ b/mftp-doctor/env.example.py @@ -1,2 +1,3 @@ -TOPIC_URL = "https://ntfy.sh/metakgp-mftp" # NTFY topic to send doctors' notifications on -EMAIL = "abc@xyz.com" # Email to send doctors' notifications on \ No newline at end of file +DOCTOR_TOPIC_URL = "https://ntfy.sh/metakgp-mftp" # NTFY topic to send doctors' notifications on +TOPIC_URL = "https://ntfy.sh/metakgp-mftp" # NTFY topic to which mftp sends notifications (set the same topic as in mftp config) +EMAIL = "abc@xyz.com" # Email to send doctors' notifications on diff --git a/mftp-doctor/mftp-doctor.py b/mftp-doctor/mftp-doctor.py index f1d396b..94138d5 100644 --- a/mftp-doctor/mftp-doctor.py +++ b/mftp-doctor/mftp-doctor.py @@ -5,7 +5,7 @@ import requests import argparse from datetime import datetime -from env import TOPIC_URL, EMAIL +from env import DOCTOR_TOPIC_URL, TOPIC_URL, EMAIL def get_logs(): client = docker.from_env() @@ -27,6 +27,8 @@ def parse_latest_runtime_logs(logs): parts = last_part_with_timestamp.split(delim) if len(parts) == 2: timestamp = parts[0].strip() + global last_notification_sent_time + last_notification_sent_time = timestamp latest_runtime_logs = parts[1].strip() else: timestamp = "NULL" @@ -50,14 +52,48 @@ def check_error(logs): else: logging.info(" NO ERROR(s) DETECTED!") +def check_downtime(): + downtime_threshold = 30 -def send_notification(logs): + if last_notification_sent_time == "NULL": + logging.info(" LAST SENT TIME IS NULL, SKIPPING DOWNTIME CHECK") + return + + try: + last_time = datetime.strptime(last_notification_sent_time, '%H:%M:%S %d-%m-%Y') + diff = (datetime.now() - last_time).total_seconds() / 60 + + if diff > downtime_threshold: + logging.info(f" DOWNTIME DETECTED (Last log was {diff:.2f} minutes ago)") + + try: + body = f"\nDOWNTIME DETECTED.\n\nPlease check the CDC Noticeboard from your ERP account until MFTP is back online.\n" + body += ''' +-------------- + +⚠️ DISCLAIMER ⚠️ + +MFTP is unofficial. Not affiliated with CDC, ERP, or Placement Committee. Do not rely solely on MFTP for updates. MFTP-related issues cannot be used as arguments with official authorities. + +-------------- + ''' + resp = send_notification(body, TOPIC_URL) + except Exception as e: + logging.error(f" FAILED TO SEND NOTIFICATION : {str(e)}") + finally: + logging.info(f" NOTIFICATION STATUS : {resp}") + else: + logging.info(" NO DOWNTIME DETECTED") + except Exception as e: + logging.error(f" FAILED TO CHECK DOWNTIME : {str(e)}") + +def send_notification(logs, topic_url=DOCTOR_TOPIC_URL): query_params = f"message={logs}" - request_url = f"{TOPIC_URL}?{query_params}" + request_url = f"{topic_url}?{query_params}" headers = { "Priority": "5", - "Tags": "warning,skull,rotating_light,mftp,error", + "Tags": "warning,mftp,error", "Title": "MFTP encountered an error", "Markdown": "yes" } @@ -82,11 +118,14 @@ def health_check(): delim = ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" logging.info(f" [ LATEST RUNTIME LOGS | {timestamp} ] \n{delim}\n{latest_runtime_logs}\n{delim}") + check_downtime() check_error(latest_runtime_logs) args = parse_args() logging.basicConfig(level=logging.INFO) +last_notification_sent_time = "NULL" + while True: now = datetime.now() print(f"================ <<: {now.strftime('%H:%M:%S %d-%m-%Y')} :>> ================", flush=True) @@ -97,4 +136,4 @@ def health_check(): break print("[PAUSED FOR 2 MINUTES]", flush=True) - time.sleep(120) \ No newline at end of file + time.sleep(120)