geoffroy-aubry/supervisor

监控脚本执行,记录标准输出、标准错误和退出代码,并添加时间戳,确保在开始、成功、警告或错误时发送电子邮件通知。

v1.8.1 2015-05-04 22:58 UTC

This package is not auto-updated.

Last update: 2024-09-28 13:58:11 UTC


README

最新稳定版本 构建状态  估计代码覆盖率: 87% (553 of 638 lines).

监控脚本执行,记录 stdoutstderr 和退出代码,并添加时间戳,确保在启动、成功、警告或错误时发送电子邮件通知……以及其他许多功能。

技术 : Supervisor 使用 Bash,只有单元测试使用 PHP。

支持的操作系统 : Debian/Ubuntu Linux,FreeBSD/OS X。

目录

功能

通用

  • 监控脚本执行,记录 stdoutstderr 和退出代码
  • stdout 的每一行前加上秒级的时间戳。
  • 执行 ID 唯一标识每次脚本执行。用于:supervisor.info.logsupervisor.error.log<script>_<exec_id>.info.log<script>_<exec_id>.error.log
  • 可以阻止并行脚本执行 (仅限 Debian/Ubuntu Linux)。如果执行时间过长,这很有用……
  • 可以指定一个配置文件来加载(覆盖默认配置文件)。
  • 完全可配置的标签系统,允许执行脚本通过 stdout 动态指定警告、mailto、邮件附件、发起者等。
  • 自动日志存档机制。
  • 显示过去几天内 Supervisor 的活动摘要,包括每天每个被监控脚本的最终状态。
  • 处理 CSV 输出,配置文件中定义了字段分隔符、字段封装符和要监视的字段数量。
  • 添加适当的信号处理和中断:SIGHUPSIGINTSIGQUITSIGTERM 现在已传输到被监控脚本。

通知

  • 确保在以下事件(可配置)上发送电子邮件通知:启动、成功、警告或错误。捕获退出代码、致命错误、异常……
  • 所有邮件都包含执行的脚本 stdoutstderr 的内容,以 Gzip 附件形式提供。
  • 邮件可以完全自定义。只需在命令行上提供你的文件。
  • 可以在命令行上将多个外部参数注入到自定义电子邮件中。
  • Supervisor 本身由另一个进程监控,使用指数退避算法在分钟递增中发送关键电子邮件通知。

人体工程学

  • 在监控期间,除了所有日志文件外,Supervisor 还实时显示被监控脚本的输出、警告和错误,添加时间戳,并尊重颜色和缩进。还打印所有日志文件名称。

代码质量

  • 使用以下指令执行的Bash代码
    • set -o nounset:当执行参数扩展时,将未设置变量和其他参数(除了特殊参数 @*)视为错误。错误信息将被写入标准错误,非交互式shell将退出。
    • set -o pipefail:管道的返回值是最后(最右边)退出状态非零的命令的返回值,或者如果管道中的所有命令都成功退出,则为零。
  • 大量单元测试(通过PHPUnit通过PHP包装器)覆盖了几乎整个应用程序。

需求

  • Bash v4(2009)及以上版本

  • mutt,用于发送邮件通知(apt-get install muttbrew install mutt

  • 单元测试需要PHP >= 5.3.3和Xdebug

  • 仅限FreeBSD/OS X,您需要安装以下GNU工具

    $ brew install coreutils
    $ brew install gnu-sed
    $ brew install gawk

在Debian/Ubuntu Linux和FreeBSD/OS X上进行了测试。

使用

命令提示符帮助

$ supervisor.sh [-h|--help]

Help on command prompt

文本版本
Description
    Oversee script execution, recording stdout, stderr and exit code with timestamping,
    and ensure email notifications will be sent (on start, success, warning or error).

Usage
    supervisor [OPTION]… <script-path> [<script-parameters>]
    supervisor [-c <conf-file>] --archive=<min-days>
    supervisor [-c <conf-file>] --monitor
    supervisor [-c <conf-file>] --summarize

Options
    --archive=<min-days>
        Archive in Gzip supervisor's logs older than <min-days>.

    -c <conf-file>, --conf=<conf-file>
        Specify a configuration file to load in addition to the default one,
        namely '/conf/supervisor-dist.sh'.

    --customized-mails=<file>
        Path to a Bash script customizing sent mails by redefining some of
        the sendMailOn[Init|Success|Warning|Error]() functions.
        See --param option.

    --exec-id=<string>
        Allow to force execution id, used in mails and name of logs.
        By default: YYYYMMDDHHIISS_XXXXX, where X are random digits.

    --extra-param-mode=[only-value|with-name|none]
        Two extra parameters are added to the end of <script-parameters>: a unique
        execution ID and name of file recording script's stderr. with-name mode prefixes
        values with '--exec-id=' and '--error-log-file=' respectively.
        By default: only-value.

    -h, --help
        Display this help.

    --mail-instigator=<email>
        Specify who executed the supervisor.

    --mail-to=<email>
        Add a new recipient's email address. Multiple --mail-to options may be used.

    --monitor
        Check whether supervisor's error log file is empty. If not, then send critical
        email notifications using an exponential backoff algorithm in minute increments.
        Typically called every minute with a cron job:
            * * * * * <user> /path/to/supervisor.sh --conf=<conf-file> --monitor

    -p <key>=<value>, --param=<key>=<value>
        Allow to inject multiple external parameters into customized emails.
        Assign the value <value> to the Bash variable $EXT_<key>.
        See --customized-mails option.

    --summarize=<max-nb-days>
        Display a summary of supervisor's activity during last <max-nb-days> days,
        including final status per day and per supervised script.
        Also send this summary by email.

    <script-path>
        Executable script to oversee.

    <script-parameters>
        Optional oversaw script's parameters.

Exit status
      0 if and only if no error
     65 Missing script name!
     66 Script '…' not found!
     67 Script '…' is not executable!
     68 Exit code changed from 0 to 68 due to errors.
     69 Another instance of '…' is still running with supervisor!
     71 Customized mails file not found: '…'
     72 Invalid Mutt command: '…'
    xxx Any code not null returned by user script

退出状态

退出状态列表

  • 0 如果且仅如果没有错误
  • 65 缺少脚本名称!
  • 66 脚本 '…' 未找到!
  • 67 脚本 '…' 不可执行!
  • 68 由于错误,退出代码从0更改为68。
  • 69 '…' 的另一个实例仍在运行中,带有supervisor!
  • 71 找不到自定义邮件文件:'…'
  • 72 无效的mutt命令:'…'
  • 用户脚本返回的非空代码

成功执行

如果且仅当标准错误为空、退出状态为0且没有警告时,执行成功。

一个简短的例子,这里在Bash中,但无论语言如何

#!/usr/bin/env bash

echo Title:
echo -e '\033[0;30m┆\033[0m   \033[1;32mgreen level 1'
echo -e '\033[0;30m┆\033[0m   \033[0;30m┆\033[0m   \033[1;33myellow level 2'
echo 'END'

输出

Successful output

如果配置文件中将SUPERVISOR_MAIL_SEND_ON_STARTUP设置为1

Mail on startup

请注意,Supervisor除了脚本参数外,还添加了两个参数

  • 唯一的执行ID
  • 记录脚本stderr的文件名

如果配置文件中将SUPERVISOR_MAIL_SEND_ON_SUCCESS设置为1

Mail on success

supervisor.info.log.20131006223705_01765.gz附件的内容

2013-10-06 22:37:05 58cs;20131006223705_01765;/usr/local/lib/supervisor/tests/resources/bash_colored_simple.sh;START
2013-10-06 22:37:05 78cs;20131006223705_01765;/usr/local/lib/supervisor/tests/resources/bash_colored_simple.sh;OK

bash_colored_simple.sh.20131006223705_01765.info.log.gz附件的内容

2013-10-06 22:37:05 58cs;[SUPERVISOR] START
2013-10-06 22:37:05 74cs;Title:
2013-10-06 22:37:05 75cs;┆   green level 1
2013-10-06 22:37:05 76cs;┆   ┆   yellow level 2
2013-10-06 22:37:05 77cs;END
2013-10-06 22:37:05 78cs;[SUPERVISOR] OK

请注意,颜色已被删除,但缩进被保留。

错误

如果标准错误不为空或退出状态与0不同,则执行将以错误状态结束。

PHP致命错误

我们将观察一个抛出致命错误的PHP脚本

<?php

undefined_fct();

输出

Error output

如果配置文件中将SUPERVISOR_MAIL_SEND_ON_ERROR设置为1

Mail on error

supervisor.info.log.20131006223703_01618.gz附件的内容

2013-10-06 22:37:03 42cs;20131006223703_01618;/usr/local/lib/supervisor/tests/resources/php_fatal_error.php;START
2013-10-06 22:37:03 59cs;20131006223703_01618;/usr/local/lib/supervisor/tests/resources/php_fatal_error.php;ERROR

php_fatal_error.php.20131006223703_01618.info.log.gz附件的内容

2013-10-06 22:37:03 42cs;[SUPERVISOR] START
2013-10-06 22:37:03 59cs;[SUPERVISOR] ERROR

php_fatal_error.php.20131006223703_01618.error.log.gz附件的内容

PHP Fatal error:  Call to undefined function undefined_fct() in /usr/local/lib/supervisor/tests/resources/php_fatal_error.php on line 4
PHP Stack trace:
PHP   1. {main}() /usr/local/lib/supervisor/tests/resources/php_fatal_error.php:0
[SUPERVISOR] Exit code not null: 255

其他错误

同样,下面提供的脚本以错误状态结束。

请注意,当标准错误非空而退出状态为0时,Supervisor将退出状态从0更改为68(参见退出状态)。

PHP通知

tests/resources/php_notice.php的内容

<?php

$a = $b;

结果在php_notice.php.[…].error.log.gz附件中

PHP Notice:  Undefined variable: b in /usr/local/lib/supervisor/tests/resources/php_notice.php on line 4
PHP Stack trace:
PHP   1. {main}() /usr/local/lib/supervisor/tests/resources/php_notice.php:0
[SUPERVISOR] Exit code changed from 0 to 68 due to errors.
PHP异常

tests/resources/php_exception.php的内容

<?php

throw new RuntimeException("It's an error!\n", 42);

结果在php_exception.php.[…].error.log.gz附件中

PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'It's an error!
' in /usr/local/lib/supervisor/tests/resources/php_exception.php:4
Stack trace:
#0 {main}
  thrown in /usr/local/lib/supervisor/tests/resources/php_exception.php on line 4
[SUPERVISOR] Exit code not null: 255
PHP标准错误

tests/resources/php_stderr.php的内容

<?php

// file_put_contents('php://stderr', "It's an error!\n");
// or:
fwrite(STDERR, "It's an error!\n");

结果在php_stderr.php.[…].error.log.gz附件中

It's an error!
[SUPERVISOR] Exit code changed from 0 to 68 due to errors.
退出非空

tests/resources/bash_exit_not_null.sh的内容

#!/usr/bin/env bash

exit 42

结果在bash_exit_not_null.sh.[…].error.log.gz附件中

[SUPERVISOR] Exit code not null: 42

标签

标签允许用户脚本将一些信息发送到supervisor。

标签是方括号之间的字符串——例如:[warning]——用于受监督脚本的输出。标签必须位于行的开头或仅由制表符——由SUPERVISOR_LOG_TABULATION定义——或空格 precede——标签必须占用整行。

警告

如果成功执行的脚本输出中包含警告标记,则其状态将从 成功 变更为 警告

默认配置:SUPERVISOR_WARNING_TAG='[WARNING]'

如果配置文件中 SUPERVISOR_MAIL_SEND_ON_WARNING 设置为 1

Mail on error

请注意,警告将与上下文2行一起列出。

调试跟踪

默认情况下,带有调试标记的消息在Supervisor的输出中是隐藏的(但仍然存在于 <script>_<exec_id>.info.log 中)。将 SUPERVISOR_SHOW_DEBUG_MSG 设置为 1 以显示它们。

默认配置

SUPERVISOR_DEBUG_TAG='[DEBUG]'
SUPERVISOR_SHOW_DEBUG_MSG=0

与电子邮件相关的标记

默认配置

SUPERVISOR_MAILTO_TAG='[MAILTO]'
SUPERVISOR_MAIL_ATTACHMENT_TAG='[MAIL_ATTACHMENT]'

待文档

有时需要确保脚本只执行一次。为此,请在配置文件中将 SUPERVISOR_LOCK_SCRIPT 设置为 1。仅适用于Debian/Ubuntu Linux,否则请留为 0。

# Lock script against parallel run (0|1)
SUPERVISOR_LOCK_SCRIPT=1

输出示例

Example of lock

发送的邮件示例

Example of sent e-mail

自定义邮件

待文档

被监控的 Supervisor

待文档

存档

将所有早于 <min-days> 天的Supervisor日志存档为Gzip格式。

Archiving

监控

检查Supervisor的错误日志文件是否为空。如果不为空,则使用指数退避算法以分钟为单位发送关键电子邮件通知。将 supervisor.info.logsupervisor.error.log 文件以Gzip格式附加。

通常每分钟由cron作业调用一次

* * * * * <user> /path/to/supervisor.sh --conf=<conf-file> --monitor

单元测试生成的邮件

Critical error

总结

显示最近 <max-nb-days> 天内Supervisor的活动摘要,包括每天以及每个受监督脚本的最终状态。还将此摘要通过电子邮件发送到 SUPERVISOR_MAIL_TO 列表。

Summary

安装

  1. 移动到您想要存储源代码和克隆存储库的目录

    $ git clone https://github.com/geoffroy-aubry/Supervisor.git
  2. 您应该在 stable 分支上。如果不是,切换您的克隆到该分支

    $ cd Supervisor && git checkout stable
  3. 创建自己的配置文件并修改它

    $ cp conf/supervisor-dist.sh conf/supervisor.sh

    注意:文件 conf/supervisor-dist.sh 总是会被加载。然后加载带有 --conf 选项指定的可选配置文件(覆盖)。但如果找不到 --conf 选项,则如果存在,则加载 conf/supervisor.sh

  4. 如果您必须监督生成CSV输出的脚本,则安装 Awk CSV解析器 组件

  5. 您可以为 supervisor.sh 创建一个符号链接

    $ sudo ln -s /path/to/src/supervisor.sh /usr/local/bin/supervisor

它已准备好使用

$ supervisor --help

版权与许可

根据GNU Lesser General Public License v3 (LGPL版本3)授权。有关详细信息,请参阅 LICENSE 文件。

变更日志

有关详细信息,请参阅 CHANGELOG 文件。

持续集成

Build Status  代码覆盖率估计: 87% (553 of 638 lines).

需要PHP >= 5.3.3和Xdebug。

创建自己的配置文件并修改它

$ cp conf/phpunit-dist.php conf/phpunit.php

使用 PHPUnit 运行单元测试

$ vendor/bin/phpunit --configuration conf/phpunit-dist.xml

在FreeBSD/OS X上,您必须排除有关独占执行(SUPERVISOR_LOCK_SCRIPT)的测试

$ vendor/bin/phpunit --configuration conf/phpunit-dist.xml

Git 分支模型

开发所使用的git分支模型是twgit工具所描述和辅助的模型:https://github.com/Twenga/twgit