Exemple #1
0
def check_base_sections(config: configparser.RawConfigParser):
    edited = False
    try:
        for i in ['service', 'logging', "notify", 'tasklist']:
            try:
                if not config.has_section(i):
                    print(f"ERROR: no section {i}")
                    edited = write_section(i, default[i])

                    if i == 'tasklist':
                        for taskName in ["disk_c", "app_log", "my_app", "my_http_server"]:
                            write_section(taskName, default[taskName])

            except Exception as e:
                print(e)
                continue

        if edited:
            print("WARNING: created new sections in config file. Restart me to apply them")
            sleep(3)
            raise SystemExit(1)
    except Exception as e:
        print(f"ERROR: Fail to create configuration file: {e}")
        sleep(3)
        raise SystemExit(1)
Exemple #2
0
    def verify_log_task(sec: str, parent: dict = None):
        try:
            if parent:
                if not parent['workDir']:
                    if not parent['exePath']:
                        raise Exception(f'not found parameter exePath in [{parent["task"]}]')
                    else:
                        path = parent['exePath']
                else:
                    path = parent['workDir']

                if not path.endswith('/'):
                    path = path + '/'

                cfg["tasks"]["logTask"][parent['task']] = tmp = {}
                tmp["file"] = config.get(sec, "file").replace('{{appDir}}', path)
            else:
                cfg["tasks"]["logTask"][sec] = tmp = {}
                tmp["file"] = config.get(sec, "file")

            tmp["tmpl"] = [i.strip() for i in config.get(sec, "templates").split(';')]
        except Exception as e:
            log.error(f"incorrect parameters in [{sec}]: {e}")
            sleep(3)
            raise SystemExit(1)
Exemple #3
0
def get_svc_params() -> list:
    try:
        return [
            config.get("service", "Name"),
            config.get("service", "DisplayName"),
            config.get("service", "Description")]
    except Exception as e:
        e = f"incorrect parameters in [Service]: {e}"
        if 'log' in locals():
            log.error(e)
        else:
            print(e)
        sleep(3)
        raise SystemExit(1)
Exemple #4
0
def open_config() -> configparser.RawConfigParser:
    try:
        open(f"{homeDir}{cfgFileName}", encoding='utf-8')
    except IOError:
        open(f"{homeDir}{cfgFileName}", 'tw', encoding='utf-8')

    config = configparser.RawConfigParser(allow_no_value=True)
    config = lowcase_sections(config)

    try:
        config.read(f"{homeDir}{cfgFileName}")
    except Exception as e:
        print(f"Fail to read configuration file: {e}")
        sleep(3)
        raise SystemExit(1)
    return config
Exemple #5
0
def load_notifier(cfg: dict, log: logging.Logger) -> Notify:
    try:
        name = cfg["notify"]["type"]
        if name != '':
            log.info(f'Load notifier {name}')
            # TODO import *
            # but now for pyInstaller need like
            # import notifier.email
            # import notifier.discord
            # import notifier.slack
            # notifier = getattr(__import__(f'notifier.{name}'), name)
            # notify = notifier.Notify(name)

            # на случай упаковки в бинарник, но тогда нужно всю стандартную либу включать
            # dict_obj = {}
            with open(f'{homeDir}notifier/{name}.py', encoding='utf-8') as src:
                scrCode = src.read()

            a = globals()
            # exec(scrCode, globals(), dict_obj)
            # notify = dict_obj['Notify'](name)
            exec(scrCode, globals(), globals())
            notify = a['Notify'](name)

            try:
                if not config.has_section(name):
                    log.warning(f'Create new section {name}')
                    if write_section(name, notify.defaultCfg):
                        log.warning("created new sections in config file. Restart me to apply them")
                        sleep(3)
                        raise SystemExit(1)
            except Exception as e:
                log.error(f"Fail to load notify configuration: {e}")

            cfg["notify"][name] = notify.load_config(config, cfg['notify']['proxy'])
        return notify
    except ImportError:
        log.error(f'Fail import notifier: {name}: {traceback.format_exc()}')
        raise SystemExit(1)
    except AttributeError as e:
        log.error(f'Wrong notifier: {e}')
        raise SystemExit(1)
    except Exception:
        log.error(f'Fail load notifier: {traceback.format_exc()}')
        raise SystemExit(1)
Exemple #6
0
def create_logger(config: configparser.RawConfigParser) -> (logging.Logger, logging.Logger, logging.StreamHandler):
    level = logging.INFO
    logSize = 10240
    logCount = 5
    try:
        if not config.getboolean("logging", "enable"):
            level = 0
        else:
            logLevel = config.get("logging", "loglevel").lower()
            if logLevel == "full":
                level = logging.DEBUG

            logSize = config.getint("logging", "logmaxsizekbs")
            logCount = config.getint("logging", "logmaxfiles")
    except Exception as e:
        print("WARNING: Check parameters for Logging.", str(e))
        sleep(3)
        raise SystemExit(1)

    log_formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')

    my_handler = RotatingFileHandler(
        f"{homeDir}logs/AppWatch.log",
        maxBytes=logSize * 1024,
        backupCount=logCount,
        encoding='utf-8')
    my_handler.setFormatter(log_formatter)

    console = logging.StreamHandler(stream=sys.stdout)  # вывод в основной поток
    console.setFormatter(log_formatter)
    console.setLevel(level)
    # logging.getLogger('root').addHandler(console)

    log = logging.getLogger('AppWatch')
    log.addHandler(my_handler)
    log.setLevel(level)
    log.addHandler(console)

    # disable requests logging
    logging.getLogger('urllib3.connectionpool').setLevel(logging.CRITICAL)

    return log, console
Exemple #7
0
    def verify_scheduler() -> list:
        ls = []
        try:
            active = config.getint('tasklist', "active")
            cfg["tasks"]["intervalCheckMin"] = config.getint('tasklist', "intervalCheckMin") * 60
            log.info(f"Activated {active} tasks")

            if active <= 0:
                raise Exception('Schedule is enabled, but no one task is active')
            else:
                for n in range(1, active + 1):
                    taskName = config.get('tasklist', str(n))
                    if not config.has_section(taskName):
                        raise Exception(f'Not found task section {taskName}')
                    else:
                        ls.append(taskName)
            return ls
        except Exception as e:
            log.error(f"incorrect parameters in [tasklist]: {e}")
            sleep(3)
            raise SystemExit(1)
Exemple #8
0
    def __load_templates(self, log: logging.Logger):
        log.info(f"Load templates.cfg")
        try:
            _ = open(f"{homeDir}templates.cfg", encoding='utf-8')
        except IOError:
            open(f"{homeDir}templates.cfg", 'tw', encoding='utf-8')

        config2 = configparser.RawConfigParser(comment_prefixes=('#', ';', '//'), allow_no_value=True)
        try:
            config2.read(f"{homeDir}templates.cfg", encoding="utf-8")
            for s in config2.sections():
                if s not in self._tmpl:
                    self._tmpl[s] = {}
                for p, v in config2.items(s):
                    self._tmpl[s][p] = v

            if len(self._tmpl) == 0:
                raise Exception("templates.cfg is empty")

        except Exception as e:
            print("Error to read configuration file:", str(traceback.format_exc()))
            sleep(3)
            raise SystemExit(1)
Exemple #9
0
    def verify_notify():
        try:
            cfg["notify"]["localName"] = config.get("notify", "localName")
            cfg["notify"]["localIp"] = config.get("notify", "localIp")
            log.info("Local server is %s (%s)" % (cfg["notify"]["localIp"], cfg["notify"]["localName"]))
        except Exception as e:
            log.error(f"incorrect parameters in [notify]: {e}")
            sleep(3)
            raise SystemExit(1)

        try:
            cfg["notify"]["resendTime"] = config.getint("notify", "resendTimeoutM")
            cfg["notify"]["onlyChanges"] = config.getboolean("notify", "onlyChanges")
            cfg["notify"]["type"] = config.get("notify", "type").lower()
            if cfg["notify"]["type"].strip() == '':
                raise Exception(f'Wrong Notify type: {cfg["notify"]["type"]}')

            cfg["notify"]["useproxy"] = config.getboolean("notify", "useproxy")
            if cfg['notify']["useproxy"]:
                log.warning("Using proxy for notifier")

                if not config.has_section('proxy'):
                    if write_section('proxy', default['proxy']):
                        log.warning("created new sections in config file. Restart me to apply them")
                        sleep(3)
                        raise SystemExit(1)

                cfg['notify']['proxy'] = {'http': {}, 'https': {}}
                added = False
                for k in cfg['notify']['proxy']:
                    if config.has_option('proxy', k):
                        added = True
                        cfg['notify']['proxy'][k] = config.get('proxy', k)

                if not added:
                    raise Exception(f"Ebabled Proxy, but no one proxy added")

        except Exception as e:
            log.error("%s" % e)
            sleep(3)
            raise SystemExit(1)
Exemple #10
0
    def verify_tasks(taskList: list):
        for task in taskList:
            try:
                # disk tasks
                if config.has_option(task, 'disk'):
                    cfg["tasks"]["diskTask"][task] = tmp = {}
                    tmp["diskWarn"] = config.getint(task, "Warning")
                    tmp["critFree"] = config.getint(task, "Critical")
                    tmp["diskUsage"] = config.get(task, "disk")
                    log.info(f'monitoring disk space: {tmp["diskUsage"]}')
                    continue

                # log tasks
                if config.has_option(task, 'file'):
                    verify_log_task(task)
                    continue

                # process tasks
                jobListTmp = {}
                jobListTmp['task'] = task
                jobListTmp['exe'] = config.get(task, "exe")
                jobListTmp['doRestart'] = config.getboolean(task, "doRestart")
                jobListTmp['alwaysWork'] = config.getboolean(task, "alwaysWork")
                jobListTmp['restartTime'] = config.getint(task, "timeForRestartingSec")
                jobListTmp['whatStart'] = whatStart = config.get(task, "whatStart")

                if config.has_option(task, 'exePath'):
                    jobListTmp['exePath'] = config.get(task, "exePath").replace('\\', '/', -1)
                    if not jobListTmp['exePath'].endswith('/'):
                        jobListTmp['exePath'] = jobListTmp['exePath'] + '/'
                else:
                    jobListTmp['exePath'] = None

                if config.has_option(task, 'workdir'):
                    jobListTmp['workDir'] = config.get(task, "workdir").replace('\\', '/', -1)
                    if not jobListTmp['workDir'].endswith('/'):
                        jobListTmp['workDir'] = jobListTmp['workDir'] + '/'

                    jobListTmp['checkPath'] = jobListTmp['workDir']
                else:
                    jobListTmp['workDir'] = None
                    jobListTmp['checkPath'] = jobListTmp['exePath']

                if not config.has_option(task, 'exePath') and not config.has_option(task, 'workDir'):
                    raise Exception("set any parameter: exePath, workDir ")

                if config.has_option(task, 'timeForResponse'):
                    jobListTmp['respTime'] = config.getint(task, "timeForResponse")
                else:
                    jobListTmp['respTime'] = 10

                jobListTmp['checkUrl'] = config.getboolean(task, "checkUrl")
                if jobListTmp['checkUrl']:
                    jobListTmp['url'] = config.get(task, "url")

                if whatStart == 'exe':
                    if not config.has_option(task, 'exePath'):
                        raise Exception("Used whatStart=exe, but no parameter exePath")

                    if config.has_option(task, 'exeKey'):
                        jobListTmp['exeKey'] = config.get(task, "exeKey")
                    else:
                        jobListTmp['exeKey'] = ''
                elif whatStart == 'command':
                    jobListTmp['command'] = config.get(task, "command")
                elif whatStart == 'service':
                    jobListTmp['service'] = config.get(task, "service")
                else:
                    raise Exception('Wrong parameter whatStart. Allowed: exe, command, service')

                if config.has_option(task, 'logInspector'):
                    jobListTmp['logInspector'] = config.get(task, 'logInspector')
                    verify_log_task(jobListTmp['logInspector'], jobListTmp)

                cfg["tasks"]["jobList"][task] = jobListTmp
            except Exception as e:
                log.error(f"incorrect parameters in [{task}]: {e}")
                sleep(3)
                raise SystemExit(1)
Exemple #11
0
            raise Exception(f"No script {fileName}. Try to set full path.")
        except AttributeError as e:
            raise Exception(f'Wrong script: {e}')
        except Exception as e:
            raise Exception(f'Fail import script: {e}')

    for sec in ['diskTask', 'logTask', 'jobList']:
        for k, v in cfg['tasks'][sec].items():
            if config.has_option(k, 'eventScript'):
                scriptName = config.get(k, 'eventScript')
                log.info(f"loading script {scriptName} ({k})")
                v['eventScript'] = load_script(scriptName)
    return cfg


if __name__ != "__main__":
    try:
        create_dirs([f"{homeDir}{'logs'}"])
    except Exception as e:
        print(e)
        sleep(3)
        raise SystemExit(-1)

    config = open_config()
    check_base_sections(config)
    log, console = create_logger(config)
    cfg = verify_config(config, log)
    cfg = load_event_scripts(cfg)
    templater = Templater(log)
    notify = load_notifier(cfg, log)