在某些日志输出时重新启动 systemd 单元

在某些日志输出时重新启动 systemd 单元

我正在尝试将程序作为 systemd 单元运行。它最初并不是设计为 systemd 单元,而且它似乎有时会将错误发布到 stdout 而不是 stderr,同时在消息前面加上。我希望有一种方法可以让 systemd 监视关键字的日志输出并在这种情况下重新启动服务,Error而不是尝试修改程序并重建它。Error

有没有办法实现这一点,无论它是 systemd 中原生的还是通过以某种方式将该程序包装在管道中?

答案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()

相关内容