夜莺开源监控模板函数有哪些一览?

摘要:本文介绍夜莺开源项目(Nightingale)的模板函数,夜莺内置了很多模板函数,可以对告警事件做一些渲染调整,方便 On-call 人员根据告警事件处理告警。 本文大纲: 夜莺开源项目简介 夜莺模板函数用途场景 夜莺模板函数分类 附加查询
本文介绍夜莺开源项目(Nightingale)的模板函数,夜莺内置了很多模板函数,可以对告警事件做一些渲染调整,方便 On-call 人员根据告警事件处理告警。 本文大纲: 夜莺开源项目简介 夜莺模板函数用途场景 夜莺模板函数分类 附加查询函数 格式化函数 字符串处理函数 时间处理函数 数学运算函数 数据处理函数 夜莺项目简介 夜莺监控(Nightingale)是一款侧重告警的监控类开源项目。类似 Grafana 的数据源集成方式,夜莺也是对接多种既有的数据源,不过 Grafana 侧重在可视化,夜莺是侧重在告警引擎、告警事件的处理和分发。 夜莺监控项目,最初由滴滴开发和开源,并于 2022 年 5 月 11 日,捐赠予中国计算机学会开源发展委员会(CCF ODC),为 CCF ODC 成立后接受捐赠的第一个开源项目。 其开源仓库地址: 代码:https://github.com/ccfos/nightingale 文档:https://n9e.github.io/ 夜莺模板函数用途场景 夜莺项目中有两个地方会用到模板: 告警规则。在告警规则的备注、附加信息等字段里可以使用 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 类型的数值 使用示例: 查询监控指标 {{ $metrics := query "mem_available_percent" }} {{ range $metrics }} 机器: {{ .Labels.ident }} 内存使用率: {{ .Value }} {{ end }} 可以在告警规则的附加信息中,使用此模板函数来实现告警时查询额外信息的需求 查询监控指标时,使用告警事件某个标签过滤 {{ $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 主要字段 字段 类型 说明 使用示例 .Id int64 告警事件ID 告警ID: {{ .Id }} .Cate string 告警类别 类别: {{ .Cate }} .Cluster string 集群名称 集群: {{ .Cluster }} .DatasourceId int64 数据源ID 数据源: {{ .DatasourceId }} .GroupId int64 业务组ID 业务组ID: {{ .GroupId }} .GroupName string 业务组名称 业务组: {{ .GroupName }} .RuleId int64 规则ID 规则ID: {{ .RuleId }} .RuleName string 规则名称 规则: {{ .RuleName }} .RuleNote string 规则备注 备注: {{ .RuleNote }} .RuleProd string 规则产品线 产品线: {{ .RuleProd }} .RuleAlgo string 规则算法 算法: {{ .RuleAlgo }} .Severity int 告警级别(1-3) {{ if eq .Severity 1 }}P1级告警{{ end }} .PromQl string PromQL查询语句 查询: {{ .PromQl }} .PromForDuration int 持续时间阈值(秒) 持续: {{ .PromForDuration }}秒 .PromEvalInterval int 评估间隔(秒) 评估间隔: {{ .PromEvalInterval }}秒 .RunbookUrl string 运维手册URL <a href="{{ .RunbookUrl }}">运维手册</a> .TargetIdent string 目标标识 目标: {{ .TargetIdent }} .TargetNote string 目标备注 {{ .TargetNote }} .TriggerTime int64 触发时间戳 {{ .TriggerTime | timeformat }} .TriggerValue string 触发值 当前值: {{ .TriggerValue }} .TagsMap map[string]string 标签键值对 主机: {{ .TagsMap.hostname }} .TagsJSON []string 标签数组 {{ range .TagsJSON }}{{ . }} {{ end }} .AnnotationsJSON map[string]string 注解键值对 {{ .AnnotationsJSON.description }} .NotifyChannels []string 通知渠道 {{ range .NotifyChannelsJSON }}{{ . }}{{ end }} .NotifyGroups []string 通知组 {{ range .NotifyGroupsJSON }}{{ . }}{{ end }} .NotifyCurNumber int 当前通知次数 第{{ .NotifyCurNumber }}次通知 .FirstTriggerTime int64 首次触发时间 首次告警: {{ .FirstTriggerTime | timeformat }} .Claimant string 认领人 认领人: {{ .Claimant }} 使用示例 // 基础信息访问 告警名称:{{ .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 }}