通过 MQTT 从 Kapacitor 发送警报

导航至

很久很久以前(在一个遥远的星系),我 写过关于 使用我拥有的这个小 GlowOrb 来显示来自 Kapacitor 的警报。它真的很酷,从那时起我就一直用它来进行演示,效果非常好。但是,我总觉得必须通过 Node-Red 端点来管道传输它,将警报转换为要在 GlowOrb 上显示的颜色值,这有点笨拙。

当我前几天在做其他事情时——难道不总是这样吗?你正在做某事,突然对完全不相关的事情有了一个绝妙的想法,接下来你就知道,你正在追逐一只 松鼠!所以我追逐了那只松鼠,这就是我想出的结果。

我在我们的一个内部 Slack 频道上发帖说,如果我可以将 Kapacitor 警报发送到 MQTT 代理,那就太棒了,这时我被告知,从 v1.4 开始,我就可以做到这一点——事实证明我不知道,因为 ARM64 版本在 v1.2 时停止了更新。现在这个问题已经修复了。因此,如果我能让它工作,我就可以绕过 Node-Red 实例,并将我的颜色警报直接写入控制 MQTT 代理。

所以我开始着手实现它。

没那么快。事实证明,这比我想象的要困难。我阅读了 文档 ——谁会这样做呢?——但它仍然无法工作。那是因为文档中遗漏了一些重要的信息。最重要的是,您必须编辑 kapacitor.conf 文件并取消注释以下行

# MQTT client configuration.
# Mutliple different clients may be configured by
# repeating [[mqtt]] sections.
[[mqtt]]
 enabled = true
 # Unique name for this broker configuration
 name = "localhost"
 # Whether this broker configuration is the default
 default = true
 # URL of the MQTT broker.
 # Possible protocols include:
 # tcp - Raw TCP network connection
 # ssl - TLS protected TCP network connection
 # ws - Websocket network connection
 url = "tcp://localhost:1883

事实证明,这是过程中的关键步骤。所以现在我可以将消息发布到我的 MQTT 服务器了。第一步完成!

但是如何发布什么信息呢?同样,文档有点稀疏(我很快就会针对文档提出一个拉取请求,以便为之后的所有人更清楚地说明其中一些内容)。

所以在我的 Chronograf 实例中,我创建了一个新的 TICK 脚本——好吧,实际上我开始修改我为旧帖子编写的那个!——我想出了这个

trigger
 |alert()
 .crit(lambda: abs("chng") > crit)
 .stateChangesOnly()
 .message(parseTemp)
 .id(idVar)
 .idTag(idTag)
 .levelTag(levelTag)
 .durationField(durationField)
 .mqtt('colorChange')
 .qos(1)

它确实奏效了,所以我将为您逐步讲解。首先,当 'change' 变量大于 'crit' 的值时,我们触发 alert()。很简单。我们将发布 message(parseTemp),其中包含 id, idTag, levelTag 等——实际上这些都不是必要的,因为我只使用了 message() 部分。我将把它放在 mqtt 代理上的 colorChange 主题下,qos 值为 1。

现在是棘手的部分。parseTemp 业务。GlowOrb 希望接收仅包含十六进制字符串颜色值的消息。Node-Red 节点对传入的值进行了简单的转换

node.log(msg.payload.data.Series[0].values[0][2])
const currentTemp = msg.payload.data.Series[0].values[0][2];
node.log(currentTemp);
const colorCodes = [
    [90, "#ff0000"],
    [88, "#ff4000"],
    [86, "#ff8000"],
    [84, "#ff8000"],
    [82, "#ffff00"],
    [80, "#bfff00"],
    [78, "#80ff00"],
    [76, "#40ff00"],
    [74, "#00ff00"],
    [72, "#00ff40"],
    [70, "#00ff80"],
    [68, "#00ffbf"],
    [66, "#00ffff"],
    [64, "#00bfff"],
    [62, "#0080ff"],
    [60, "#0040ff"],
    [58, "#0000ff"],
    [56, "#4000ff"],
    [54, "#8000ff"],
];
const code = colorCodes.find((temp, code) => currentTemp >= temp)
const payload = code ? code[1] : "#bf00ff"
return {payload, val: currentTemp};

但那是 JavaScript,我需要在 TICKScript 中完成此操作。所以请坚持住,因为这将会变得有点难看。

首先,我必须复习一下模板变量。事实证明我已经在使用一个了

var message = '{{ index .Fields "value" }}'

但这一个将会更加棘手。非常棘手。

我计算了时间窗口内最小值和最大值之间的差异,如果变化大于阈值,我就会触发警报。因此,我需要根据触发警报的最大值来设置 GlowOrb 的颜色。该模板变量看起来像这样

var message = '{{ index .Fields "max" }}'

不要犯我犯过的错误,寻找 “max.value”,否则你将花费半天时间想知道为什么它不起作用。相信我这一点。现在,对于 if-then-else 部分的乐趣。同样,我将为此使用模板变量,但正如我之前所说,这是一个难看的变量。

var parseTemp = ''' {{ if (( index .Fields "max" ) gt 90 ) }} #ff0000 {{ else if 
    (( index .Fields "max" ) gt 88 ) }} #ff4000{ { else if 
    (( index .Fields "max" ) gt 86 ) }} #ff8000 {{ else if 
    (( index .Fields "max" ) gt 84 ) }} #ff8000 {{ else if 
    (( index .Fields "max" ) gt 82 ) }} #ffff00 {{ else if 
    (( index .Fields "max" ) gt 80 ) }} #bfff00 {{ else if 
    (( index .Fields "max" ) gt 78 ) }} #80ff00 {{ else if 
    (( index .Fields "max" ) gt 76 ) }} #40ff00 {{ else if 
    (( index .Fields "max" ) gt 74 ) }} #00ff00 {{ else if 
    (( index .Fields "max" ) gt 72 ) }} #00ff40 {{ else if 
    (( index .Fields "max" ) gt 70 ) }} #00ff80 {{ else if 
    (( index .Fields "max" ) gt 68 ) }} #00ffbf {{ else if 
    (( index .Fields "max" ) gt 66 ) }} #00ffff {{ else if 
    (( index .Fields "max" ) gt 64 ) }} #00bfff {{ else if 
    (( index .Fields "max" ) gt 62 ) }} #0080ff {{ else if 
    (( index .Fields "max" ) gt 60 ) }} #0040ff {{ else if 
    (( index .Fields "max" ) gt 58 ) }} #0000ff {{ else if 
    (( index .Fields "max" ) gt 56 ) }} #4000ff {{ else if 
    (( index .Fields "max" ) gt 54 ) }} #8000ff {{ else }} #bf00ff {{ end }}'''

你不能说我没有警告你!不幸的是,我找不到一种方法使其更易读。就是这样。保存它并触发温度变化事件后,我的 MQTT 代理必须说这个

MQTT ClientScreenSnapz001

成功了!!现在我所要做的就是更改我的 GlowOrb 以从代理上的 colorChange 主题读取,我就完成了。不再需要写入运行 Node-Red 的 http 服务器、运行一堆 Javascript 并发布回 MQTT 代理。现在我可以直接从 Kapacitor 发布到 MQTT 代理并完成它了!

我也将开始将我的一堆其他警报转移到 MQTT。

继续 安装 InfluxDB 和其余的 TICK Stack,并开始使用 MQTT 完成您的数据收集、分析和警报。