跳转到主要内容

Coal Mine - 定期任务执行监控器

项目描述

Coal Mine - 定期任务执行监控器

主页位于 Github。版本可在 PyPI 上找到。请支持此项目 在Patreon 上。

什么是Coal Mine?

定期、重复的任务在计算机中无处不在,因此在系统管理和运营中,最常见的难题之一是确保这些任务按预期执行。设计任务以报告错误是必要的,但不足以解决问题;如果任务根本未运行(崩溃的守护进程,crontab配置错误)或运行速度远慢于预期怎么办?

Coal Mine提供了一种简单但强大的工具来解决这个问题。简而言之

  • 每个重复任务都与Coal Mine的“金丝雀”相关联。
  • 任务在执行完毕时触发金丝雀。
  • 金丝雀知道任务应该多久执行一次。
  • 当金丝雀迟到时,Coal Mine会通过电子邮件发出警报,当迟到的金丝雀恢复时再次发出警报。
  • 煤矿记录了每个矿鸟被触发的历史(部分)。

使用“矿鸟”来跟踪应该定期执行的任务。当任务执行时触发矿鸟。当矿鸟晚于预定时间时,通过电子邮件发出警报。当晚于预定时间的矿鸟恢复时,再次发出警报。记录矿鸟触发时间的部分历史。

当未暂停的矿鸟的截止日期通过时,服务器立即通知。同样,当之前晚于预定时间的矿鸟被触发时,服务器也会立即通知。

先决条件

  • Python 3.2
  • 用于存储的MongoDB(欢迎提出拉取请求以添加其他存储引擎)
  • requirements.txt中列出的要求
  • 开发时,requirements_dev.txt中列出的要求

概念

Coal Mine提供了两个接口,一个是REST API,另一个是命令行界面(CLI)。由于触发矿鸟只需通过GET或POST查询来调用其端点,因此最好通过API进行触发,这样CLI就不需要在每个运行监控任务的系统上安装。另一方面,对于管理操作,CLI通常更简单。

Coal Mine存储和显示的所有时间戳均为UTC。

操作

通过CLI或API可以在矿鸟上执行以下操作

  • 创建
  • 删除
  • 重新配置
  • 获取信息
  • 暂停 -- 停止监控和警报
  • 恢复
  • 触发
  • 列出 -- 所有的矿鸟或匹配搜索条件的矿鸟

Coal Mine的安全措施非常基础。如果服务器配置了可选的认证密钥,那么在除触发操作外的所有操作中都必须指定该密钥。

数据

在创建或更新时指定以下矿鸟属性

  • 名称
  • 描述
  • 周期性 -- 矿鸟晚于预定时间的最大秒数,或者以下格式描述的计划,允许矿鸟的周期性随时间变化
  • 零个或多个通知电子邮件地址

这些由Coal Mine创建和维护

  • slug -- 矿鸟的名称,小写,将空格和下划线转换为连字符,并移除其他非字母数字字符
  • 当矿鸟创建时生成的一个由八个小写字母组成的随机标识符,保证在数据库中与其他矿鸟唯一
  • 晚于预定状态(布尔值)
  • 通知状态(布尔值)指示是否需要为该矿鸟发送通知(在处理通知时由单独的后台任务使用)
  • 暂停状态(布尔值)
  • 矿鸟应触发以避免晚于预定时间的截止日期
  • 触发历史记录,当大于1000个或(大于100个且超过一周)时进行修剪

计划周期性

Coal Mine允许矿鸟的周期性根据时间、日期、星期几等自动变化。这在三种情况下很有用

  1. 重复的任务在不同的时间以不同的频率执行;
  2. 连续重复的任务在不同的时间完成所需的时间或多或少;或者
  3. 对重复任务延迟响应的紧迫性在不同的时间变化。

要指定矿鸟的周期性变化,而不是只指定秒数,你可以指定一系列由分号分隔的crontab-like指令。以下是一个例子,拆分为多行以提高可读性

# 5-minute delays are ok on weekends ;
* * * * sat,sun 300 ;
# 5-minute days are ok overnight ;
* 0-12 * * mon-fri 300 ;
# otherwise, we require a shorter periodicity ;
* 13-23 * * mon-fri 90

备注

  • 每个指令的最后一个字段是周期性值,即允许在指定时间范围内触发之间的最大秒数。

  • 如上所述,尽管示例显示为拆分为多行,但在提供给Coal Mine时必须在单行中指定。

  • 请注意,像上面显示的这样的注释在您指定的煤矿时间表中确实是允许的——它们不仅仅是示例中的装饰——但您需要记住用分号结束它们。

  • 时间表指令不能重叠。例如,这不会起作用,因为第二个指令在每周的午夜到中午之间与第一个指令重叠。

      * * * * sat,sun 60 ;
      * 0-11 * * * 90
    
  • 如果一个金丝雀的时间表有间隔,那么在这段时间内金丝雀实际上是暂停的。例如,在这个时间表中,金丝雀将在整个周六暂停。

      * * * * sun 300 ;
      * * * * mon-fri 60
    
  • 与煤矿中的其他一切一样,这里指定的小时和分钟是以UTC为单位的。

  • 当您使用周期性时间表创建或更新一个金丝雀时,返回给您的金丝雀数据将包括一个“periodicity_schedule”字段,显示您指定的计划如何执行。时间表将延伸到足够远的未来,以便每个指定的指令至少显示一次,或者为一个星期,以较长的为准。

安装和配置

服务器

  1. pip install coal-mine
  2. 创建/etc/coal-mine.ini(见下面)或使用环境变量
  3. 运行coal-mine &
  4. 将其放入/etc/rc.local或根据需要放入其他位置,以确保在重启时重新启动。

服务器配置文件

服务器配置文件coal-mine.ini可以放在服务器启动的当前目录、/etc/usr/local/etc中。(如果您需要将其放在其他位置,请修改server.py中顶部附近的目录列表。)

文件显然是INI格式。以下是它可以或必须包含的节和设置

  • [logging] -- 可选
    • file -- 日志文件路径;否则日志输出到stderr
    • rotate -- 如果为true,则在日志文件过大时进行轮换
    • max_size -- 在轮换之前的最大日志文件大小(默认:1048576)
    • backup_count -- 要保留的轮换日志文件数量(默认:5)
  • [mongodb] -- 必需
    • hosts -- MongoDB URI或以逗号分隔的一个或多个主机名列表
    • database -- 数据库名。煤矿将在数据库中创建一个名为“canaries”的集合。如果hosts包含MongoDB URI,则省略
    • username -- 如果不需要认证或hosts包含URI,则省略
    • password -- 如果不需要认证或如果hosts包含URI,则省略
    • replicaSet -- 如果使用replicaset且hosts不是URI,则必须指定
    • 其他参数将通过MongoClient传递
      • 例如,可以将tls设置为True或False
  • [email]
    • sender(必需)-- 放在通知电子邮件的From行中的电子邮件地址
    • host(可选)-- 连接到的SMTP主机
    • port(可选)-- 连接到的SMTP端口
    • username(可选)-- SMTP用户名,如果指定了密码,则必须指定
    • password(可选)-- SMTP密码,如果指定了用户名,则必须指定
  • [wsgi] -- 可选
    • port -- 服务器应监听的端口号(默认:80)
    • auth_key -- 如果不为空,则必须指定与所有API请求(除“trigger”外)同名参数的指定密钥。

通过环境变量配置

如果设置了环境变量MONGODB_URI,则服务器将从环境变量而不是coal-mine.ini读取其配置。(即,将不会搜索或读取配置文件)。以这种方式配置时,不支持日志配置,mongodb配置文件部分被替换为MONGODB_URI变量,其余配置设置如下所示

  • email.sender -> EMAIL_SENDER
  • email.host -> SMTP_HOST
  • email.port -> SMTP_PORT
  • email.username -> SMTP_USERNAME
  • email.password -> SMTP_PASSWORD
  • wsgi.port -> WSGI_PORT
  • wsgi.auth_key -> WSGI_AUTH_KEY

将服务器部署到Heroku

源代码树中有一个Procfile,允许您将此应用程序部署到Heroku。这是一个尚未广泛测试的新功能,如果您遇到任何问题,请提交错误报告!以下是一些简要步骤:

  1. 创建一个新Heroku应用程序来保存它。
  2. 通过MONGODB_URI配置变量,使用附加组件(我认为ObjectRocket可以工作)、MongoDB Atlas、您自己的自托管MongoDB集群或其他方式将MongoDB数据库连接到Heroku应用程序。只要Heroku可以连接到它,并且其完整URI位于MONGODB_URI中,数据库的存储位置无关紧要。
  3. 设置EMAIL_SENDERSMTP_HOSTSMTP_PORTSMTP_USERNAMESMTP_PASSWORD。您需要将SMTP附加组件添加到Heroku应用程序或拥有一个您可以使用的SMTP服务器;如果您使用附加组件,它可能会使用不同的名称来调用这些设置,因此您需要将它们复制到Coal Mine期望的名称中。
  4. WSGI_AUTH_KEY设置为长且随机的值,因为您不希望任何人都能在网上干扰您的Coal Mine实例。
  5. 将代码推送到Heroku应用程序。
  6. 确保应用程序配置为至少运行一个Web dyno(默认情况下应该会发生)和恰好1个工作 dyno。

完成所有这些后,您需要根据以下说明配置您的CLI以与Heroku应用程序通信。确保在配置CLI时,在主机名前指定https://

CLI

  1. pip install coal-mine
  2. cmcli configure [--host server-host-name] [--port server-port] [--auth-key key | --no-auth-key]

--host参数可以接受URL基础(即,http://server-host-namehttps://server-host-name)。如果,例如,您已经将Coal Mine服务器放在SSL代理后面,那么CLI需要使用SSL连接到它(您可能需要这样做,例如,如果像上面描述的那样在Heroku上部署),这将非常有用。

CLI将其配置存储在~/.coal-mine.ini中。请注意,认证密钥以纯文本形式存储。CLI需要但不在INI文件中存储的任何配置参数都必须在使用CLI时明确在命令行上指定。

使用Coal Mine

CLI

Coal Mine CLI,cmcli,提供了对Coal Mine全部功能的便捷访问。

为了使CLI更容易使用,您可以像上面那样进行配置,但您还可以选择在每次使用时指定服务器连接信息。此外,命令行上指定的连接信息会覆盖存储的配置。

以下是一些示例命令:

cmcli create --help

cmcli create --name 'My Second Canary' --periodicity $((60*60*25))  # $((60*60*25)) is 25 hours
cmcli trigger --id aseprogj
cmcli delete --slug 'my-second-canary'

运行cmcli --help获取更多信息。

对于针对单个金丝雀的操作的命令,您可以使用--id--name--slug来识别金丝雀。请注意,对于update命令,如果您想更新金丝雀的名称,您将需要通过--id--slug来识别它,因为在这种情况下,--name参数用于指定新名称。

API使用示例

示例命令

$ coal-mine &
[1] 7564
$ curl 'http://coal-mine-server/coal-mine/v1/canary/create?name=My+First+Canary&periodicity=3600'
{
    "status": "ok",
    "canary": {
        "deadline": "2015-03-19T02:08:44.885182",
        "id": "fbkvlsby",
        "paused": false,
        "description": "",
        "periodicity": 3600,
        "name": "My First Canary",
        "slug": "my-first-canary",
        "emails": [],
        "history": [
            [
                "2015-03-19T01:08:44.885182",
                "Canary created"
            ]
        ],
        "late": false
    }
}
$ curl 'http://coal-mine-server/fbkvlsby?comment=short+form+trigger+url'
{
    "recovered": false,
    "unpaused": false,
    "status": "ok"
}
$ curl 'http://coal-mine-server/coal-mine/v1/canary/trigger?slug=my-first-canary&comment=long+form+trigger+url'
{
    "recovered": false,
    "unpaused": false,
    "status": "ok"
}
$ curl 'http://coal-mine-server/coal-mine/v1/canary/get?name=My+First+Canary'
{
    "canary": {
        "paused": false,
        "name": "My First Canary",
        "history": [
            [
                "2015-03-19T01:11:56.408000",
                "Triggered (long form trigger url)"
            ],
            [
                "2015-03-19T01:10:42.608000",
                "Triggered (short form trigger url)"
            ],
            [
                "2015-03-19T01:08:44.885000",
                "Canary created"
            ]
        ],
        "emails": [],
        "id": "fbkvlsby",
        "late": false,
        "slug": "my-first-canary",
        "deadline": "2015-03-19T02:11:56.408000",
        "periodicity": 3600,
        "description": ""
    },
    "status": "ok"
}

以下详细说明了所有API端点。

监控cron作业

 0 0 * * * my-backup-script.sh && (curl http://coal-mine-server/fbkvlsby &>/dev/null)

API参考

所有API端点都作为http(s) GET请求提交。结果以JSON返回。

所有结果都有一个“status”字段,在成功时为“ok”,在失败时为“error”。失败还会返回合理的HTTP错误状态代码。

API中的布尔字段应指定为“true”、“yes”或“1”表示真,或“false”、“no”、“0”或空字符串表示假。响应中的布尔字段是标准JSON,即“true”或“false”。

API返回的时间戳总是UTC。

创建金丝雀

端点: /coal-mine/v1/canary/create

副作用

将金丝雀添加到数据库。在当前时间创建历史记录,其评论为“金丝雀创建”。除非指定“暂停”,否则将截止日期设置为当前时间加周期性。

必需参数

  • 名称
  • periodicity
  • auth_key(如果服务器启用了身份验证)

可选参数

  • description - 未指定时为空
  • email - 为多个地址重复指定;未指定时不发送通知
  • paused - 允许创建已暂停状态的金丝雀

响应与get()中显示的相同。

删除金丝雀

端点: /coal-mine/v1/canary/delete

必需参数

  • name、id或slug
  • auth_key

响应

{'status': 'ok'}

更新金丝雀

端点: /coal-mine/v1/canary/update

副作用

更新指定的金丝雀属性。如果更新了周期性且金丝雀未暂停,则将截止日期更新为最新的历史时间戳加周期性,并设置迟到状态。如果新截止日期在现在之前,则设置迟到状态。如果金丝雀从未迟到变为迟到或反之,则发送通知。

必需参数

  • id或slug(不是 name,只能指定以更新名称和slug)
  • auth_key

可选参数

  • 名称
  • periodicity
  • 描述
  • email - 指定单个值“-”以清除现有的电子邮件地址

响应与get()中显示的相同。

获取金丝雀

端点: /coal-mine/v1/canary/get

必需参数

  • name、id或slug
  • auth_key

响应

{'status': 'ok',
 'canary': {'name': name,
           'description': description,
           'id': identifier,
           'slug': slug,
           'periodicity': seconds,
           'emails': [address, ...],
           'late': boolean,
           'paused': boolean,
           'deadline': 'YYYY-MM-DDTHH:MM:SSZ',
           'history': [['YYYY-MM-DDTHH:MM:SSZ', comment], ...]}}

列出金丝雀

端点: /coal-mine/v1/canary/list

必需参数

  • auth_key

可选参数

  • verbose - 包含每个金丝雀的所有查询输出
  • paused - 布尔值,仅列出暂停/未暂停的金丝雀
  • late - 布尔值,仅列出迟到/及时的金丝雀
  • search - 字符串,正则表达式,用于匹配名称、标识符和slug

响应

{'status': 'ok',
 'canaries': [{'name': name,
             'id': identifier},
            ...]}

如果“verbose”为true,则每个金丝雀的JSON包含上述所有字段,而不仅仅是名称和标识符。

触发金丝雀

端点: /coal-mine/v1/canary/trigger

也: /identifier,在这种情况下,“id”参数是隐含的

请注意,服务器将接受触发器的POST请求以及GET请求,这样您就可以在期望能够POST的应用程序中使用触发器。POST的内容被忽略;即使使用POST,API参数也必须以查询字符串的形式指定。

副作用

将迟到状态设置为false。将截止日期设置为现在加周期性。添加历史记录。修剪历史记录。暂停金丝雀。如果金丝雀之前是迟到的,则生成通知电子邮件。

必需参数

  • name、id或slug

可选参数

  • comment - 存储在触发记录的历史中

响应

{'status': 'ok', 'recovered': boolean, 'unpaused': boolean}
  • recovered - 表示此触发器之前金丝雀是否已迟到
  • unpaused - 表示此触发器之前金丝雀是否已暂停

暂停金丝雀

端点: /coal-mine/v1/canary/pause

副作用

清除截止日期。如果需要,将迟到状态设置为false。暂停金丝雀。添加关于暂停的历史记录。修剪历史记录。

必需参数

  • name、id或slug
  • auth_key

可选参数

  • comment

响应与get()中显示的相同。

取消暂停金丝雀

端点: /coal-mine/v1/canary/unpause

副作用

将截止日期设置为现在加周期性。取消暂停金丝雀。添加关于取消暂停的历史记录。修剪历史记录。

必需参数

  • name、id或slug
  • auth_key

可选参数

  • comment

响应与get()中显示的相同。

Quis custodiet ipsos custodes?

显然,如果您依赖Coal Mine来通知您有事情出错,您需要确保Coal Mine本身保持运行。一种方法是设置一个cron作业,定期触发金丝雀并生成输出(crond会将其通过电子邮件发送给您),如果触发失败。

0 * * * * (curl http://coal-mine-server/atvywzoa | grep -q -s '"status": "ok"') || echo "Failed to trigger canary."

我还推荐使用Papertrail等日志监控服务来监控和警报Coal Mine日志中的错误。

联系人

Github

Email

PyPI

贡献者

煤炭矿井由Jonathan Kamens创建,并得到了来自Quantopian的杰出团队的精心设计帮助。感谢Quantopian支持本项目的开发和开源。

维护包

测试

测试期望使用pytest运行。安装完requirements.txtrequirements_dev.txt中的所有包后,运行python3 -m pytest

构建

安装requirements.txtrequirements_dev.txt中的需求后,执行python3 -m build以构建包。

上传到PyPI

我们目前正在使用Twine上传到PyPI。您需要安装requirements.txtrequirements_dev.txt中的需求才能使用它。您还需要配置它。有关更多信息,请参阅Twine文档

开发哲学

使用Python。

做好一件简单的事。现在有几个类似的项目做得比本项目尝试做的更多。

尽可能使实现简单直接。代码应该尽量小。从阅读中应该可以明显看出每件事的作用。

最小化外部依赖。如果某件事我们可以简单地自己完成,那么就无需为了使用第三方包而使用它。

替代方案

煤炭矿井的替代方案包括

我们选择编写新的东西,而不是使用现有的,有以下几个原因

  • 我们希望对我们的监控服务的稳定性和可靠性有更多的控制,而商业替代方案无法提供。
  • 我们希望对监控的周期性有更细粒度的控制,并确保当监控延迟时,我们会立即收到通知,这是不是所有替代方案都能保证的。
  • 我们喜欢Python。
  • 我们喜欢开源。

待办事项

(欢迎提交拉取请求!)

其他存储引擎。

其他通知机制。

Web用户界面。

在电子邮件通知中链接Web用户界面。

如果哨兵长时间延迟,是否重复通知?甚至不确定我是否想要这个。

更好的认证?

支持显示时间戳的时区本地化。

服务器支持SSL。

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

coal_mine-0.7.1.tar.gz (55.5 kB 查看哈希值)

上传时间 源代码

构建分发

coal_mine-0.7.1-py3-none-any.whl (37.5 kB 查看哈希值)

上传时间 Python 3

支持