写点什么

夜莺开源监控,模板函数一览

作者:巴辉特
  • 2025-08-12
    北京
  • 本文字数:4779 字

    阅读完需:约 16 分钟

本文介绍夜莺开源项目(Nightingale)的模板函数,夜莺内置了很多模板函数,可以对告警事件做一些渲染调整,方便 On-call 人员根据告警事件处理告警。


本文大纲:


  • 夜莺开源项目简介

  • 夜莺模板函数用途场景

  • 夜莺模板函数分类

  • 附加查询函数

  • 格式化函数

  • 字符串处理函数

  • 时间处理函数

  • 数学运算函数

  • 数据处理函数

夜莺项目简介


夜莺监控(Nightingale)是一款侧重告警的监控类开源项目。类似 Grafana 的数据源集成方式,夜莺也是对接多种既有的数据源,不过 Grafana 侧重在可视化,夜莺是侧重在告警引擎、告警事件的处理和分发。


夜莺监控项目,最初由滴滴开发和开源,并于 2022 年 5 月 11 日,捐赠予中国计算机学会开源发展委员会(CCF ODC),为 CCF ODC 成立后接受捐赠的第一个开源项目。


其开源仓库地址:


夜莺模板函数用途场景

夜莺项目中有两个地方会用到模板:


  • 告警规则。在告警规则的备注、附加信息等字段里可以使用 go template 自定义字段内容

  • 消息模板。在把告警发给各个通知媒介时,不同的媒介会有不同的要求,比如邮件内容是 HTML 格式,钉钉机器人是 Markdown,此时也需要使用 go template 模板来渲染内容


这两个地方支持的模板函数是相同的。只是可以引用的字段略有差异。这里我们以告警规则为例,说明各个模板函数的用途。

夜莺模板函数分类

夜莺模板函数大致可以分为:


  • 附加查询函数

  • 格式化函数

  • 字符串处理函数

  • 时间处理函数

  • 数学运算函数

  • 数据处理函数

附加查询函数

query

功能描述:执行 Prometheus 查询并返回结果。这是一个特殊的模板函数,用于在告警注解中动态查询指标数据。


函数签名


func(promql string, param ...int64) QueryResult
复制代码


参数说明


  • promql: Prometheus 查询语句

  • param: 可选参数,指定数据源 ID。如果不指定,使用当前告警规则的数据源


返回值QueryResult 类型,包含查询结果的样本数据,每个样本包含:


  • Labels: map[string]string 类型的标签集合

  • Value: float64 类型的数值


使用示例


  1. 查询监控指标


{{ $metrics := query "mem_available_percent" }}{{ range $metrics }}  机器: {{ .Labels.ident }}  内存使用率: {{ .Value }}{{ end }}
复制代码


可以在告警规则的附加信息中,使用此模板函数来实现告警时查询额外信息的需求



  1. 查询监控指标时,使用告警事件某个标签过滤


{{ $memMetrics := query (printf "mem_available_percent{ident=\"%s\"}" .TagsMap.ident) }}{{ range $memMetrics }}  机器: {{ .Labels.ident }}  内存使用率: {{ .Value }}{{ end }}
复制代码

格式化函数

humanize

功能描述:将数字格式化为人类可读的形式,使用 SI 前缀(k, M, G, T 等)


使用示例


{{ "1234567" | humanize }}     // 输出: 1.23M{{ "0.00123" | humanize }}      // 输出: 1.23m{{ "1000000000" | humanize }}   // 输出: 1.00G
复制代码

humanize1024

功能描述:将数字格式化为人类可读的形式,使用二进制前缀(Ki, Mi, Gi, Ti 等)


使用示例


{{ "1048576" | humanize1024 }}    // 输出: 1Mi{{ "1073741824" | humanize1024 }} // 输出: 1Gi{{ "2048" | humanize1024 }}       // 输出: 2ki
复制代码

humanizeDuration

功能描述:将秒数转换为人类可读的时间格式


使用示例


{{ "3661" | humanizeDuration }}   // 输出: 1h 1m 1s{{ "86400" | humanizeDuration }}  // 输出: 1d 0h 0m 0s{{ "0.5" | humanizeDuration }}    // 输出: 500ms
复制代码

humanizePercentage

功能描述:将小数转换为百分比格式(乘以 100)


使用示例


{{ "0.8567" | humanizePercentage }}  // 输出: 85.67%{{ "0.05" | humanizePercentage }}    // 输出: 5.00%{{ "1" | humanizePercentage }}       // 输出: 100.00%
复制代码

humanizePercentageH

功能描述:直接格式化为百分比(不乘以 100)


使用示例


{{ "85.67" | humanizePercentageH }}  // 输出: 85.67%{{ "5" | humanizePercentageH }}      // 输出: 5.00%{{ "100" | humanizePercentageH }}    // 输出: 100.00%
复制代码

formatDecimal

功能描述:格式化数字为指定小数位数


使用示例


{{ formatDecimal "3.14159" 2 }}   // 输出: 3.14{{ formatDecimal "10.5" 3 }}      // 输出: 10.500{{ formatDecimal "0.123456" 4 }}  // 输出: 0.1235
复制代码

printf

功能描述:格式化输出字符串,特别优化了对字符串数字的处理(会自动尝试将字符串转换为浮点数)


函数签名


func Printf(format string, value interface{}) string
复制代码


特点


  • 如果传入的是字符串类型的数字,会自动转换为浮点数进行格式化

  • 支持标准的 Go 格式化占位符


使用示例


// 格式化浮点数(字符串会自动转换){{ printf "%.2f" "3.14159" }}        // 输出: 3.14{{ printf "%.2f" .TriggerValue }}    // 将触发值格式化为2位小数
// 百分比格式化{{ printf "%.1f%%" "85.67" }} // 输出: 85.7%{{ printf "使用率: %.2f%%" .TriggerValue }} // 输出: 使用率: 85.67%
// 科学计数法{{ printf "%e" "1234567" }} // 输出: 1.234567e+06{{ printf "%.2e" .TriggerValue }} // 输出: 8.57e+01
// 整数格式化(需要注意类型){{ printf "%d" 42 }} // 输出: 42
// 字符串格式化{{ printf "主机 %s 告警" .TagsMap.hostname }} // 输出: 主机 server01 告警
// 组合使用{{ printf "[%s] %.2f%% (阈值: %.0f%%)" .RuleName .TriggerValue 80.0 }}// 输出: [CPU告警] 85.67% (阈值: 80%)
复制代码

字符串处理函数

escape

功能描述:URL 路径转义


使用示例


{{ "hello world" | escape }}    // 输出: hello%20world{{ "a/b/c" | escape }}          // 输出: a%2Fb%2Fc
复制代码

unescaped

功能描述:将字符串作为 HTML 输出(不转义)


使用示例


{{ "<b>Bold Text</b>" | unescaped }}  // 输出原始HTML: <b>Bold Text</b>{{ "<script>alert('hi')</script>" | unescaped }}  // 输出原始脚本标签
复制代码

urlconvert

功能描述:将字符串转换为 URL 类型


使用示例


{{ "http://example.com" | urlconvert }}  // 转换为URL类型
复制代码

toUpper

功能描述:转换为大写


使用示例


{{ "hello world" | toUpper }}  // 输出: HELLO WORLD{{ .TagsMap.env | toUpper }}    // 将标签值转为大写
复制代码

toLower

功能描述:转换为小写


使用示例


{{ "HELLO WORLD" | toLower }}  // 输出: hello world{{ .TagsMap.DC | toLower }}     // 将标签值转为小写
复制代码

title

功能描述:将字符串转换为标题格式(首字母大写)


使用示例


{{ "hello world" | title }}    // 输出: Hello World{{ "api_server" | title }}     // 输出: Api_Server
复制代码

contains

功能描述:检查字符串是否包含子串


使用示例


{{ if contains "hello world" "world" }}包含{{ end }}  // 输出: 包含{{ if contains .TagsMap.service "api" }}是API服务{{ end }}
复制代码

match

功能描述:正则表达式匹配


使用示例


{{ if match "^prod-.*" .TagsMap.env }}生产环境{{ end }}{{ if match "[0-9]+" "abc123" }}包含数字{{ end }}
复制代码

reReplaceAll

功能描述:正则表达式替换


使用示例


{{ reReplaceAll "[0-9]+" "X" "abc123def456" }}  // 输出: abcXdefX{{ reReplaceAll "\\s+" "-" "hello  world" }}    // 输出: hello-world
复制代码

split

功能描述:字符串分割


使用示例


{{ split "a,b,c" "," }}         // 返回: ["a", "b", "c"]{{ range .TagsJSON }}  标签: {{ . }}{{ end }}
复制代码

join

功能描述:字符串连接


使用示例


{{ join (split "a,b,c" ",") "-" }}  // 输出: a-b-c{{ $arr := args "hello" "world" }}{{ join $arr " " }}                 // 输出: hello world
复制代码

toString

功能描述:将任意类型转换为字符串


使用示例


{{ toString 123 }}           // 输出: "123"{{ toString 3.14 }}          // 输出: "3.14"{{ toString .Value }}        // 将数值转为字符串
复制代码

时间处理函数

timeformat

功能描述:格式化 Unix 时间戳


使用示例


{{ timeformat 1609459200 }}                       // 输出: 2021-01-01 00:00:00{{ timeformat 1609459200 "2006-01-02" }}         // 输出: 2021-01-01{{ timeformat .Timestamp "15:04:05" }}           // 输出时间部分
复制代码

timestamp

功能描述:获取当前时间的格式化字符串


使用示例


{{ timestamp }}                     // 输出: 2024-01-15 10:30:45{{ timestamp "2006-01-02" }}       // 输出: 2024-01-15{{ timestamp "15:04:05" }}         // 输出: 10:30:45
复制代码

now

功能描述:获取当前时间对象


使用示例


{{ now }}                          // 返回当前时间对象{{ now.Format "2006-01-02" }}     // 格式化当前时间{{ now.Unix }}                     // 获取Unix时间戳
复制代码

toTime

功能描述:将时间戳转换为时间对象


使用示例


{{ $t := toTime 1609459200 }}{{ $t.Format "2006-01-02" }}      // 输出: 2021-01-01
复制代码

parseDuration

功能描述:解析时间持续时间字符串


使用示例


{{ parseDuration "1h30m" }}       // 返回: 5400 (秒){{ parseDuration "24h" }}         // 返回: 86400 (秒){{ parseDuration "5m" }}          // 返回: 300 (秒)
复制代码

数学运算函数

add

功能描述:加法运算


使用示例


{{ add 10 20 }}                   // 输出: 30
复制代码

sub

功能描述:减法运算


使用示例


{{ sub 100 30 }}                  // 输出: 70
复制代码

mul

功能描述:乘法运算


使用示例


{{ mul 10 5 }}                    // 输出: 50
复制代码

div

功能描述:除法运算


使用示例


{{ div 100 5 }}                   // 输出: 20
复制代码

数据处理函数

first

功能描述:获取查询结果的第一个元素


函数签名


func(v QueryResult) (*sample, error)
复制代码


使用示例


{{ $result := query "up" }}{{ with first $result }}  第一个实例: {{ label "instance" . }} 状态: {{ value . }}{{ end }}
// 注意:在 AlertCurEvent 上下文中访问标签应使用 TagsMap第一个触发的主机: {{ .TagsMap.hostname }}
复制代码

label

功能描述:获取查询结果样本的标签值(用于 query 函数返回的 QueryResult 的单个 sample )


函数签名


func(label string, s *sample) string
复制代码


使用示例


{{ $result := query "up" }}{{ range $result }}  主机名: {{ label "hostname" . }}  环境: {{ label "env" . }}{{ end }}
复制代码

value

功能描述:获取查询结果样本的数值(用于 query 函数返回的 QueryResult 的单个 sample)


函数签名


func(s *sample) float64
复制代码


使用示例


{{ $result := query "cpu_usage" }}{{ range $result }}  CPU使用率: {{ value . }}%{{ end }}
复制代码

模板渲染上下文(AlertCurEvent)

在告警规则的注解和通知模板渲染时,模板引擎会传入 AlertCurEvent 对象作为上下文。你可以直接访问该对象的所有字段。

预定义变量

模板开始时会自动定义以下便捷变量:


  • $labels: 等同于 .TagsMap,包含所有标签的键值对

  • $value: 等同于 .TriggerValue,触发告警的值

  • $annotations: 等同于 .AnnotationsJSON,注解的键值对(仅在某些场景可用)

AlertCurEvent 主要字段

使用示例

// 基础信息访问告警名称:{{ .RuleName }}告警级别:{{ if eq .Severity 1 }}P1{{ else if eq .Severity 2 }}P2{{ else }}P3{{ end }}业务组:{{ .GroupName }}触发时间:{{ .TriggerTime | timeformat "2006-01-02 15:04:05" }}当前值:{{ .TriggerValue | humanize }}
// 使用预定义变量主机名:{{ $labels.ident }}当前值:{{ $value | humanizePercentage }}
// 条件判断{{ if gt (toFloat64 .TriggerValue) 80 }}严重:使用率超过80%{{ else if gt (toFloat64 .TriggerValue) 60 }}警告:使用率超过60%{{ end }}
// 遍历标签{{ range $k, $v := .TagsMap }} {{ $k }}: {{ $v }}{{ end }}
// 访问注解描述:{{ .AnnotationsJSON.description }}摘要:{{ .AnnotationsJSON.summary }}
复制代码


用户头像

巴辉特

关注

聊聊运维、监控、云原生 2017-09-11 加入

Open-Falcon、Nightingale、Categraf 主程,快猫星云联合创始人

评论

发布
暂无评论
夜莺开源监控,模板函数一览_Nightingale_巴辉特_InfoQ写作社区