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允许矿鸟的周期性根据时间、日期、星期几等自动变化。这在三种情况下很有用
- 重复的任务在不同的时间以不同的频率执行;
- 连续重复的任务在不同的时间完成所需的时间或多或少;或者
- 对重复任务延迟响应的紧迫性在不同的时间变化。
要指定矿鸟的周期性变化,而不是只指定秒数,你可以指定一系列由分号分隔的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”字段,显示您指定的计划如何执行。时间表将延伸到足够远的未来,以便每个指定的指令至少显示一次,或者为一个星期,以较长的为准。
安装和配置
服务器
pip install coal-mine
- 创建
/etc/coal-mine.ini
(见下面)或使用环境变量 - 运行
coal-mine &
- 将其放入
/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。这是一个尚未广泛测试的新功能,如果您遇到任何问题,请提交错误报告!以下是一些简要步骤:
- 创建一个新Heroku应用程序来保存它。
- 通过
MONGODB_URI
配置变量,使用附加组件(我认为ObjectRocket可以工作)、MongoDB Atlas、您自己的自托管MongoDB集群或其他方式将MongoDB数据库连接到Heroku应用程序。只要Heroku可以连接到它,并且其完整URI位于MONGODB_URI
中,数据库的存储位置无关紧要。 - 设置
EMAIL_SENDER
、SMTP_HOST
、SMTP_PORT
、SMTP_USERNAME
、SMTP_PASSWORD
。您需要将SMTP附加组件添加到Heroku应用程序或拥有一个您可以使用的SMTP服务器;如果您使用附加组件,它可能会使用不同的名称来调用这些设置,因此您需要将它们复制到Coal Mine期望的名称中。 - 将
WSGI_AUTH_KEY
设置为长且随机的值,因为您不希望任何人都能在网上干扰您的Coal Mine实例。 - 将代码推送到Heroku应用程序。
- 确保应用程序配置为至少运行一个Web dyno(默认情况下应该会发生)和恰好1个工作 dyno。
完成所有这些后,您需要根据以下说明配置您的CLI以与Heroku应用程序通信。确保在配置CLI时,在主机名前指定https://
。
CLI
pip install coal-mine
cmcli configure [--host server-host-name] [--port server-port] [--auth-key key | --no-auth-key]
--host
参数可以接受URL基础(即,http://server-host-name
或https://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日志中的错误。
联系人
贡献者
煤炭矿井由Jonathan Kamens创建,并得到了来自Quantopian的杰出团队的精心设计帮助。感谢Quantopian支持本项目的开发和开源。
维护包
测试
测试期望使用pytest
运行。安装完requirements.txt
和requirements_dev.txt
中的所有包后,运行python3 -m pytest
。
构建
安装requirements.txt
和requirements_dev.txt
中的需求后,执行python3 -m build
以构建包。
上传到PyPI
我们目前正在使用Twine上传到PyPI。您需要安装requirements.txt
和requirements_dev.txt
中的需求才能使用它。您还需要配置它。有关更多信息,请参阅Twine文档。
开发哲学
使用Python。
做好一件简单的事。现在有几个类似的项目做得比本项目尝试做的更多。
尽可能使实现简单直接。代码应该尽量小。从阅读中应该可以明显看出每件事的作用。
最小化外部依赖。如果某件事我们可以简单地自己完成,那么就无需为了使用第三方包而使用它。
替代方案
煤炭矿井的替代方案包括
我们选择编写新的东西,而不是使用现有的,有以下几个原因
- 我们希望对我们的监控服务的稳定性和可靠性有更多的控制,而商业替代方案无法提供。
- 我们希望对监控的周期性有更细粒度的控制,并确保当监控延迟时,我们会立即收到通知,这是不是所有替代方案都能保证的。
- 我们喜欢Python。
- 我们喜欢开源。
待办事项
(欢迎提交拉取请求!)
其他存储引擎。
其他通知机制。
Web用户界面。
在电子邮件通知中链接Web用户界面。
如果哨兵长时间延迟,是否重复通知?甚至不确定我是否想要这个。
更好的认证?
支持显示时间戳的时区本地化。
服务器支持SSL。
项目详情
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源代码分发
构建分发
coal_mine-0.7.1.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | a3bf5536c46acada5e171ff52ffdb2a2454d49a439c38022012e8bf804855148 |
|
MD5 | fdbb0af4fb96dacae08c71fa07f63f1e |
|
BLAKE2b-256 | 7f37cfc1d1085c3997f6c416804ec2fb19dac3ad52e0696ebc55c0b108bd0f89 |
coal_mine-0.7.1-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | b1fcf07cf9c5312ac16a260526bc709fcc6b6913ca936af9596b7f5d35f53b78 |
|
MD5 | 73a69fd478cefbfa170acfb8d179ff27 |
|
BLAKE2b-256 | 023c6f62d7885cd3356a0c413816bddb8fda23de7385c520c60443238a58615e |