Repository URL to install this package:
|
Version:
1.9.2 ▾
|
dship2postgis
/
check_mk_service.py
|
|---|
from gmr_underway_connect.underway_data import UnderwayDailyHandler, UnderwayNmeaHandler
from dshipparser import helpers
import email, datetime, logging
from dateutil import parser as datetime_parser
import chardet
"""
Service can be called to perform checks which will generate check_mk compatible output
see https://mathias-kettner.de/checkmk_localchecks.html
"""
#_date_response_format = '%a, %d %b %Y %H:%M:%S %z' # format of Date field in mail headers, e.g. 'Fri, 27 Apr 2018 00:08:08 +0000'
default_warn_nmea = 12
default_crit_nmea = 24
default_warn_daily = 26
default_crit_daily = 48
def get_dates_from_mails(mail_handler):
mail_ids = mail_handler.get_mail_ids(10)
if not mail_ids: # Folder is empty, no mails found
return None
status, raw_headers = mail_handler.udw_mail.get_mail_connection().fetch(mail_ids, '(BODY.PEEK[HEADER])')
dates = []
raw_dates = []
for response_part in raw_headers:
if isinstance(response_part, tuple):
part = response_part[1]
part = part.decode(chardet.detect(part)['encoding'])
msg = email.message_from_string(part)
# print(msg.keys())
raw_date = msg['Date']
raw_dates.append(raw_date)
the_date = None
try:
the_date = datetime_parser.parse(raw_date)
except ValueError as exc:
pass
if not the_date:
# after dship-update, dates like 'Di, 15 Dez 2020 00:16:42 0000' are returned
# which cannot be parsed. Alternatively, look for date in received header
# written by geomar mta
try:
raw_date = msg.get_all('received')[0].split(';')[-1]
the_date = datetime_parser.parse(raw_date)
dates.append(the_date)
except Exception:
raise ValueError(f"Could not parse date from '{raw_date}'") from exc
dates.append(the_date)
return dates
def get_age_of_mails_as_hours(mail_handler):
dates = get_dates_from_mails(mail_handler)
if dates == None: # returned when no mails were foundn in folder
return [9999]
deltas = [datetime.datetime.utcnow() - d.replace(tzinfo=None) for d in dates]
return [d.days * 24 + d.seconds // 3600 for d in deltas]
def get_age_last_nmea_mail(platform):
"""Returns age (in hours) of the last NMEA telegram found.
Age is taken from email timestamp, not NMEA timestamp!
"""
mh = UnderwayNmeaHandler(platform)
return min(get_age_of_mails_as_hours(mh))
def get_age_last_daily_mail(platform):
"""Returns age (in hours) of the last NMEA telegram found.
Age is taken from email timestamp, not NMEA timestamp!
"""
mh = UnderwayDailyHandler(platform)
return min(get_age_of_mails_as_hours(mh))
def do_check_age_nmea(platform, warn=default_warn_nmea, crit=default_crit_nmea):
return _do_check('nmea', platform, warn, crit)
def do_check_age_daily(platform, warn=default_warn_daily, crit=default_crit_daily):
return _do_check('daily', platform, warn, crit)
def _do_check(check_type, platform, warn, crit):
status = 3 # UNKNOWN
try:
if check_type == 'nmea':
age = get_age_last_nmea_mail(platform)
else:
age = get_age_last_daily_mail(platform)
if age == 9999:
status = 2 # CRITICAL
status_txt = f'CRITICAL - No {check_type} mails found for {platform}!'
elif age < warn:
status = 0 # OK
status_txt = f'OK - age of last {check_type} mail for {platform} is less than {warn} hours'
elif warn <= age < crit:
status = 1 # WARNING
status_txt = f'WARNING - age of last {check_type} mail for {platform} is more than {warn} hours'
elif crit < age:
status = 2 # CRITICAL
status_txt = f'CRITICAL - age of last {check_type} mail for {platform} is more than {crit} hours'
except Exception as e:
status = 3 # UNKNOWN
age = 'N/A'
error_str = str(e)
logging.error(f'ERROR - age check for {platform} resulted in error: {error_str}')
status_txt = f'ERROR - age check for {platform} resulted in error: {error_str}'
return f"{status} age_check_{check_type}_{platform} age={age};{warn};{crit} {status_txt}"