TL;DR InfluxDB技术小贴士——使用InfluxDB仪表板中的Flux deadman()函数可视化正常运行时间

跳转到

一个常见的DevOps用例是在主机停止报告指标时发出警报,即所谓的“死人之警报”。这可以通过使用monitor.deadman() Flux函数来完成。可以在InfluxDB UI警报部分轻松创建死人之检查,或者也可以创建一个定制的任务来发出警报。有关更多详细信息,请查看InfluxDB的检查和通知系统文章。也可以在仪表板单元格中直接使用monitor.deadman()函数。

deadman()函数的作用

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

在介绍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()

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

Visualizing uptime using Flux query and scripting language

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

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

注意额外的dead

Flux - monitor.deadman function

dead记录设置为false的主机表示它们正在积极发送数据。同样,设置为true的主机表示死人之警报;即在过去一小时没有写入任何数据。

为了在仪表板单元格中使其更易于理解,我们添加了一个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()函数会将数据解组,以便在显示时位于一个表中。为了使其可排序,可以添加另一列,其中包含原始的在线时间值,使用条件逻辑用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之上开发酷炫的物联网应用,我们非常愿意了解,请确保分享您的故事!此外,请在评论部分分享您的想法、关注点或问题。我们非常希望得到您的反馈并帮助您解决遇到的问题!