Skip to content

Instantly share code, notes, and snippets.

@hn-support
Last active March 25, 2020 14:33
Show Gist options
  • Save hn-support/e86d8ca4c04b1ab1db78f905b7b4d1a7 to your computer and use it in GitHub Desktop.
Save hn-support/e86d8ca4c04b1ab1db78f905b7b4d1a7 to your computer and use it in GitHub Desktop.

Revisions

  1. hn-support revised this gist Jul 12, 2017. 1 changed file with 2 additions and 6 deletions.
    8 changes: 2 additions & 6 deletions searchd-watchdog.py
    Original file line number Diff line number Diff line change
    @@ -80,12 +80,8 @@ def pid_exists(pid):
    """
    if pid < 0:
    return False
    if pid == 0:
    # According to "man 2 kill" PID 0 refers to every process
    # in the process group of the calling process.
    # On certain systems 0 is a valid PID but we have no way
    # to know that in a portable fashion.
    raise ValueError('invalid PID 0')
    if pid == 0 or pid == 1:
    raise ValueError('invalid PID 0 or 1')
    try:
    os.kill(pid, 0)
    except OSError as err:
  2. hn-support revised this gist Jul 12, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion searchd-watchdog.py
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@
    * * * * * flock -n ~/.searchd_live /data/web/searchd-watchdog.py --environment live --version 2 (live)
    * * * * * flock -n ~/.searchd_staging /data/web/searchd-watchdog.py --environment staging --version 2 (staging)
    July 12 2017 - Flip Hes <flip@byte.nl>
    July 12 2017 - Flip Hes <support@byte.nl>
    """
    import argparse
    import errno
  3. hn-support created this gist Jul 12, 2017.
    130 changes: 130 additions & 0 deletions searchd-watchdog.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    #!/usr/bin/env python
    """ Hypernode searchd cron watchdog
    This script checks the pid of the searchd daemon and restarts it when the service is not running
    It works for both Magento 1 and Magento 2 and for both live and staging.
    To run it, add it to the crontab of your hypernode.
    For Magento 1:
    * * * * * flock -n ~/.searchd_live /data/web/searchd-watchdog.py --environment live --version 1 (live)
    * * * * * flock -n ~/.searchd_staging /data/web/searchd-watchdog.py --environment staging --version 1 (staging)
    For Magento 2:
    * * * * * flock -n ~/.searchd_live /data/web/searchd-watchdog.py --environment live --version 2 (live)
    * * * * * flock -n ~/.searchd_staging /data/web/searchd-watchdog.py --environment staging --version 2 (staging)
    July 12 2017 - Flip Hes <[email protected]>
    """
    import argparse
    import errno
    import logging
    import os
    import sys
    import subprocess

    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger('searchd-watchdog')


    CONFIG_DICT = {
    "staging": {
    1: {
    "config": "/data/web/staging/var/sphinx/sphinx.conf",
    "pid": "/data/web/staging/var/sphinx/searchd.pid"
    },
    2: {
    "config": "/data/web/magento2_staging/var/sphinx/sphinx.conf",
    "pid": "/data/web/magento2_staging/var/sphinx/searchd.pid"
    },
    },
    "live": {
    1: {
    "config": "/data/web/public/var/sphinx/sphinx.conf",
    "pid": "/data/web/public/var/sphinx/searchd.pid"
    },
    2: {
    "config": "/data/web/magento2/var/sphinx/sphinx.conf",
    "pid": "/data/web/magento2/var/sphinx/searchd.pid"
    }
    }
    }


    def parse_arguments():
    parser = argparse.ArgumentParser(description="Searchd watchdog")
    parser.add_argument("--env", dest="environment", type=str, required=True, choices=CONFIG_DICT.keys(),
    help="The environment to watch")
    parser.add_argument('--version', dest='version', type=int, required=True, choices=[1, 2],
    help="The magento version to use")
    parser.add_argument("--log", dest="logfile", type=str, default="/data/web/sphinx.log",
    help="The log file to write all output to")
    arguments = parser.parse_args()

    return arguments


    def read_pid_file(filename):
    if not filename or not os.path.isfile(filename):
    return None
    try:
    with open(filename) as fh:
    return int(fh.read())
    except:
    return None


    def pid_exists(pid):
    """Check whether pid exists in the current process table.
    UNIX only.
    """
    if pid < 0:
    return False
    if pid == 0:
    # According to "man 2 kill" PID 0 refers to every process
    # in the process group of the calling process.
    # On certain systems 0 is a valid PID but we have no way
    # to know that in a portable fashion.
    raise ValueError('invalid PID 0')
    try:
    os.kill(pid, 0)
    except OSError as err:
    if err.errno == errno.ESRCH:
    # ESRCH == No such process
    return False
    elif err.errno == errno.EPERM:
    # EPERM clearly means there's a process to deny access to
    return True
    else:
    # According to "man 2 kill" possible error values are
    # (EINVAL, EPERM, ESRCH)
    raise
    else:
    return True


    def start_sphinx(config, logfile):
    command = '/usr/bin/nohup /usr/bin/searchd --config {} 2>&1 >> {} &'.format(config, logfile)
    try:
    subprocess.check_call(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setpgrp)
    except subprocess.CalledProcessError:
    logger.error("Failed to start searchd for config {}".format(config), file=sys.stderr)


    if __name__ == "__main__":
    arguments = parse_arguments()
    try:
    sphinx_config = CONFIG_DICT[arguments.environment][arguments.version]["config"]
    sphinx_pid = CONFIG_DICT[arguments.environment][arguments.version]["pid"]
    except KeyError:
    logger.error('Configuration for version {} and environment {} not found!'.format(arguments.version, arguments.environment))
    sys.exit(1)

    if not os.path.isfile(sphinx_config):
    logger.error('Sphinx configuration file {} not found!'.format(sphinx_config))
    sys.exit(1)

    pid = read_pid_file(filename=sphinx_pid)
    if not pid or not pid_exists(pid=pid):
    logger.info('Restarting searchd daemon for {}'.format(arguments.environment))
    start_sphinx(config=sphinx_config, logfile=arguments.logfile)