TL;DR InfluxDB 技术提示 – 在 InfluxDB 仪表板中使用 Flux deadman() 函数可视化正常运行时间

导航至

一个常见的 DevOps 用例是在主机停止报告指标时发出警报,即 deadman 警报。这可以使用 monitor.deadman() Flux 函数完成。可以在 InfluxDB UI 警报部分轻松创建 deadman(或阈值)检查,或者制作自定义任务来发出警报。查看 InfluxDB 的检查和通知系统帖子以获取更多详细信息。也可以直接在仪表板单元格中使用 monitor.deadman() 函数。

deadman() 函数的作用

deadman 函数保留每个组(主机)的最新行,添加一个 dead 列,如果最新记录发生在检查 deadman 的时间段之后,则设置为 false,如果发生在此时段之前,则设置为 true,表示 deadman。

在介绍 Flux 查询之前,有必要解释为什么需要使用 deadman() 函数。如果没有它,任何停止写入的主机都不会包含在返回的表中。

编写 Flux 查询以在仪表板单元格中使用

假设我们想要创建一个仪表板单元格,显示主机列表以及当前正常运行时间,或者如果未返回指标则显示“离线”。

首先我们导入两个包

import "influxdata/influxdb/monitor"
import "experimental"

monitor 包用于 monitor.deadman() 函数,experimental 包用于 experimental.subDuration() 函数,以请求我们要检查的过去时间段。

接下来,我们取回过去 7 天内每个主机的最新数据点的表

from(bucket: "bucket_name")
    |> range(start: -7d)
    |> filter(fn: (r) => r["_measurement"] == "system")
    |> filter(fn: (r) => r["_field"] == "uptime")
    |> group(columns: ["host"]
    |> last()

返回的数据包括每个 host 的最新记录,其中正常运行时间字段为 _value_time

Visualizing uptime using Flux query and scripting language

为了检查主机是否为 deadman;即,在过去一小时内没有写入任何数据,我们将调用 monitor.deadman() 函数

|> monitor.deadman(t: experimental.subDuration(d: 1h, from: now()))

请注意额外的 dead

Flux - monitor.deadman function

dead 记录设置为 false 的主机表示它们正在主动发送数据。同样,设置为 true 的主机表示 deadman;即,在过去一小时内没有写入数据。

为了使仪表板单元格更易于理解,我们添加一个 map() 来显示“离线”主机,否则,显示当前正常运行时间

|> map(fn: (r) => ({ r with _value: if r.dead == true then "Offline" else string(v: r._value) }))

为了显示更易于理解的正常运行时间持续时间,我们可以将秒转换为天或小时

|> map(fn: (r) => ({ r with _value: if r.dead == true then "Offline" else if 
                                           r._value > 86400 then 
                                                string(v: r._value / 86400) + " days" else
                                                string(v: r._value / 3600) + " hours"

仪表板单元格看起来像

Displaying uptime duration

完整的查询是

import "influxdata/influxdb/monitor"
import "experimental"

from(bucket: "bucket_name")
    |> range(start: -7d)
    |> filter(fn: (r) => r["_measurement"] == "system")
    |> filter(fn: (r) => r["_field"] == "uptime")
    |> monitor.deadman(t: experimental.subDuration(d: 1h, from: now()))
    |> map(fn: (r) => ({ r with uptime: if r.dead == true then "Offline" else if 
                                           r._value > 86400 then 
                                                string(v: r._value / 86400) + " days" else
                                                string(v: r._value / 3600) + " hours"
                       }))
    |> group()
    |> keep(columns: ["uptime", "host"])

请注意,last() 不是必需的,因为 monitor.deadman() 返回每个主机的最新数据点。 group() 取消数据分组,使其在一个表中以便显示。为了使其可排序,可以使用 条件逻辑 添加另一列,其中包含原始正常运行时间值,而不是 “offline” 添加 0

|> map(fn: (r) => ({ r with uptime_sort: if r.dead == true then 0 else r._value }))

关于在 InfluxDB 仪表板中使用 Flux deadman() 函数的结论

我希望这篇文章能帮助您意识到 Flux monitor.deadman() 函数不仅适用于警报和任务,也适用于仪表板。

如果您是 Flux 新手,或者正在将 InfluxQL 查询迁移到 Flux 并且需要帮助,请在我们的  社区站点Slack  频道提问。如果您正在 InfluxDB 之上开发酷炫的物联网应用程序,我们很乐意听到您的消息,请务必 分享您的故事! 此外,请在评论区分享您的想法、疑虑或问题。我们很乐意获得您的反馈并帮助您解决遇到的任何问题!