165 lines
5.2 KiB
Python
165 lines
5.2 KiB
Python
""" Telltale files helpers """
|
|
|
|
import argparse
|
|
import datetime
|
|
import logging
|
|
import os
|
|
import sys
|
|
|
|
from mylib import pretty_format_timedelta
|
|
from mylib.scripts.helpers import get_opts_parser, init_logging
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
DEFAULT_WARNING_THRESHOLD = 90
|
|
DEFAULT_CRITICAL_THRESHOLD = 240
|
|
|
|
|
|
class TelltaleFile:
|
|
"""Telltale file helper class"""
|
|
|
|
def __init__(self, filepath=None, filename=None, dirpath=None):
|
|
assert filepath or filename, "filename or filepath is required"
|
|
if filepath:
|
|
assert (
|
|
not filename or os.path.basename(filepath) == filename
|
|
), "filepath and filename does not match"
|
|
assert (
|
|
not dirpath or os.path.dirname(filepath) == dirpath
|
|
), "filepath and dirpath does not match"
|
|
self.filename = filename if filename else os.path.basename(filepath)
|
|
self.dirpath = (
|
|
dirpath if dirpath else (os.path.dirname(filepath) if filepath else os.getcwd())
|
|
)
|
|
self.filepath = filepath if filepath else os.path.join(self.dirpath, self.filename)
|
|
|
|
@property
|
|
def last_update(self):
|
|
"""Retrieve last update datetime of the telltall file"""
|
|
try:
|
|
return datetime.datetime.fromtimestamp(os.stat(self.filepath).st_mtime)
|
|
except FileNotFoundError:
|
|
log.info("Telltale file not found (%s)", self.filepath)
|
|
return None
|
|
|
|
def update(self):
|
|
"""Update the telltale file"""
|
|
log.info("Update telltale file (%s)", self.filepath)
|
|
try:
|
|
os.utime(self.filepath, None)
|
|
except FileNotFoundError:
|
|
# pylint: disable=consider-using-with
|
|
open(self.filepath, "a", encoding="utf-8").close()
|
|
|
|
def remove(self):
|
|
"""Remove the telltale file"""
|
|
try:
|
|
os.remove(self.filepath)
|
|
return True
|
|
except FileNotFoundError:
|
|
return True
|
|
|
|
@classmethod
|
|
def check_entrypoint(
|
|
cls,
|
|
argv=None,
|
|
description=None,
|
|
default_filepath=None,
|
|
default_warning_threshold=None,
|
|
default_critical_threshold=None,
|
|
fail_message=None,
|
|
success_message=None,
|
|
):
|
|
"""Entry point of the script to check a telltale file last update"""
|
|
argv = argv if argv else sys.argv
|
|
description = description if description else "Check last execution date"
|
|
parser = get_opts_parser(desc=description, exit_on_error=False)
|
|
|
|
parser.add_argument(
|
|
"-p",
|
|
"--telltale-file-path",
|
|
action="store",
|
|
type=str,
|
|
dest="telltale_file_path",
|
|
help=f"Telltale file path (default: {default_filepath})",
|
|
default=default_filepath,
|
|
required=not default_filepath,
|
|
)
|
|
|
|
default_warning_threshold = (
|
|
default_warning_threshold
|
|
if default_warning_threshold is not None
|
|
else DEFAULT_WARNING_THRESHOLD
|
|
)
|
|
default_critical_threshold = (
|
|
default_critical_threshold
|
|
if default_critical_threshold is not None
|
|
else DEFAULT_CRITICAL_THRESHOLD
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-w",
|
|
"--warning",
|
|
type=int,
|
|
dest="warning",
|
|
help=(
|
|
"Specify warning threshold (in minutes, default: "
|
|
f"{default_warning_threshold} minutes)"
|
|
),
|
|
default=default_warning_threshold,
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-c",
|
|
"--critical",
|
|
type=int,
|
|
dest="critical",
|
|
help=(
|
|
"Specify critical threshold (in minutes, default: "
|
|
f"{default_critical_threshold} minutes)"
|
|
),
|
|
default=default_critical_threshold,
|
|
)
|
|
|
|
try:
|
|
options = parser.parse_args(argv[1:])
|
|
except argparse.ArgumentError as err:
|
|
print(f"UNKNOWN - {err}")
|
|
sys.exit(3)
|
|
|
|
# Initialize logs
|
|
init_logging(options, argv[0])
|
|
|
|
telltale_file = cls(filepath=options.telltale_file_path)
|
|
last = telltale_file.last_update
|
|
if not last:
|
|
status = "UNKNOWN"
|
|
exit_code = 3
|
|
msg = (
|
|
fail_message
|
|
if fail_message
|
|
else "Fail to retrieve last successful date of execution"
|
|
)
|
|
else:
|
|
delay = datetime.datetime.now() - last
|
|
msg = (
|
|
success_message
|
|
if success_message
|
|
else "Last successful execution was {last_delay} ago ({last_date})"
|
|
).format(
|
|
last_delay=pretty_format_timedelta(delay),
|
|
last_date=last.strftime("%Y/%m/%d %H:%M:%S"),
|
|
)
|
|
|
|
if delay >= datetime.timedelta(minutes=options.critical):
|
|
status = "CRITICAL"
|
|
exit_code = 2
|
|
elif delay >= datetime.timedelta(minutes=options.warning):
|
|
status = "WARNING"
|
|
exit_code = 1
|
|
else:
|
|
status = "OK"
|
|
exit_code = 0
|
|
|
|
print(f"{status} - {msg}")
|
|
sys.exit(exit_code)
|