Как узнать, умирает ли работающий скрипт? - PullRequest
4 голосов
/ 18 февраля 2012

Так что я немного новичок в программировании и в основном самоучка, так что извините, если этот вопрос немного новичок.

У меня есть сценарий Python, который выполняется в течение длительных периодов времени (например, он загружает страницы каждые несколько секунд в течение нескольких дней за раз.) Сортировка сценария мониторинга для веб-приложения.

Время от времени что-то нарушает его, и его нужно будет перезапустить. Я довел эти события до минимума, но это по-прежнему происходит каждые несколько дней, и когда его действительно убивают, это может быть плохой новостью, если я не замечу в течение нескольких часов.

Сейчас он работает в сеансе экрана на VPS.

Может ли кто-нибудь указать мне правильное направление, если я знаю, когда сценарий умирает / и он автоматически перезапускается?

Будет ли это что-то писать в Bash? Или что-то другое? Я никогда не делал ничего подобного раньше и не знаю, с чего начать или даже искать информацию.

Ответы [ 4 ]

4 голосов
/ 18 февраля 2012

Вы можете попробовать supervisord , это инструмент для управления процессами демона.

3 голосов
/ 18 февраля 2012

Я считаю, что скрипт bash-оболочки, который выполняет скрипт python внутри цикла, должен справиться с задачей.

while true; do
    # Execute python script here
    echo "Web app monitoring script disrupted ... Restarting script."
done

Надеюсь, это поможет.

2 голосов
/ 19 февраля 2012

Вы должны демонизировать свою программу.

Как описано в Эффективный демон Python , вы можете установить и использовать python-daemon , который реализует демон хорошего поведения.спецификация PEP 3143 , "Стандартная библиотека процессов демона".

Создайте файл mydaemon.py с содержимым, подобным этому:

#!/usr/bin/env python

import daemon
import time
import logging

def do_something():
    name = 'mydaemon'
    logger = logging.getLogger(name)
    handler = logging.FileHandler('/tmp/%s.log' % (name))
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler) 
    logger.setLevel(logging.WARNING)

    while True:
        try:
            time.sleep(5)
            with open("/tmp/file-does-not-exist", "r") as f:
                f.write("The time is now " + time.ctime())
        except Exception, ex:
            logger.error(ex)

def run():
    with daemon.DaemonContext():
        do_something()

if __name__ == "__main__":
    run()

Чтобы фактически запустить его, используйте:

python mydaemon.py

, который будет порождать do_something() в пределах DaemonContext и тогда скрипт mydaemon.py выйдет.Вы можете увидеть работающего демона с: pgrep -fl mydaemon.py.Этот короткий пример просто регистрирует ошибки в файле журнала в /tmp/mydaemon.log.Вам нужно будет вручную убить демона, или он будет работать бесконечно.

Чтобы запустить собственную программу, просто замените содержимое блока try вызовом вашего кода.

2 голосов
/ 18 февраля 2012

Это зависит от того, какую неудачу вы хотите защитить.Если это просто сбой скрипта, самое простое, что нужно сделать, это обернуть вашу основную функцию в попытку / исключение:

import logging as log

while True:
    try:
        main()
    except:
        log.exception("main() crashed")

Если что-то убивает процесс Python, возможно, проще всего запустить его вцикл оболочки:

while sleep 1; do python checker.py; done

И если он выходит из строя из-за того, что машина выходит из строя… ну… Quis custodiet ipsos custodes?

Однако, чтобы ответить на ваш вопрос напрямую: абсолютно простой способпроверить, запускается ли он из оболочки, было бы grep для вывода ps:

ps | grep "python checker.py" 2>&1 > /dev/null
running=$?

Конечно, это не защищено от ошибок, но в целом это достаточно хорошо.

...