Перезапустить системный модуль на определенном выходе журнала

Я пытаюсь запустить программу как системный модуль. Первоначально он не был спроектирован как единое целое, и кажется, что он иногда отправляет сообщения об ошибках в stdout вместо stderr, в то же время префикс сообщения с Error . Вместо того, чтобы пытаться изменить программу и перестроить ее, я надеялся, что мог бы быть способ, чтобы systemd отслеживал вывод журнала для ключевого слова Error и перезапускал службу в этом случае.

Есть ли способ достижения этого, будь то встроенный в systemd или каким-либо образом, оборачивая эту программу в конвейер?

0
задан 1 July 2020 в 21:36

1 ответ

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

#!/usr/bin/env python3

import subprocess
import atexit
import sys

ALL_PROCESSES = []


def exit_handler():
    for process in ALL_PROCESSES:
        process.kill()


def main():
    global ALL_PROCESSES
    process = subprocess.Popen(<what-to-execute>,
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
    ALL_PROCESSES.append(process)
    while True:
        nextline = process.stdout.readline()
        if nextline == '' and process.poll() is not None:
            break
        if 'error' in nextline.lower():
            sys.stderr.write('Error occured, stopping child: {}'.format(nextline))
            exit_handler()
            sys.exit(1)
        sys.stdout.write(nextline)
        sys.stdout.flush()

    output = process.communicate()[0]
    exitCode = process.returncode

    if (exitCode == 0):
        return output
    else:
        raise ProcessException(command, exitCode, output)


def execute(cmd):
    popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
    for stdout_line in iter(popen.stdout.readline, ""):
        yield stdout_line
    popen.stdout.close()
    return_code = popen.wait()
    if return_code:
        raise subprocess.CalledProcessError(return_code, cmd)


atexit.register(exit_handler)

if __name__ == '__main__':
    main()
0
ответ дан 30 July 2020 в 22:16

Другие вопросы по тегам:

Похожие вопросы: