Golang模板template
背景概述
当我们在进行json
字段选取以及渲染时,我们经常会见到{{}}
,其实这就是我们今天要讲解的模板即是template。例如prometheusAlert中的模板就是使用了改语法。
必备技能
-
字段选取
❝
{{ . }} 表示json的所有域,例如:{"name":"anruo","age":18},我们使用{{ . }}就可以获取到所有的内容 {{ .name }} 就可以获取到anruo字符串。
range: 循环,当json中有列表时,我们可以使用
{{range $index,$value:=.xx}}{{$index,$value}}{{end}}
来进行取值。{{-}}: 去重空格内容
-
自定义函数
所谓自定义函数,即是我们可以自定义处理字段。例如:时间字段中的时区转换。
-
运算符
❝
eq
: ==ge
: >=gt
: >le
: <=lt
: <ne
: !=
案例演示
我们先模拟一下源数据,这里我们定义一个结构体
type Temp struct {
Name string
Age int64
Like []string
Study []Study
}
type Study struct {
Name string
School string
}
初始化template
func NewTemplate(tmpl string) (*template.Template, error) {
return template.New("anruo").Funcs(TmpFuncMap()).Parse(tmpl)
}
func TmpExcute(tmpl string, data interface{}) {
t, _ := NewTemplate(tmpl)
_ = t.Execute(os.Stdout, data)
}
func TmpFuncMap() template.FuncMap {
return template.FuncMap{
"GetLocalTime": func() string { return time.Now().String() },
"SubTime": func(oldTime string) string {
t1, _ := time.Parse("2006-01-02 15:04:05", oldTime)
t2, _ := time.Parse("2006-01-02 15:04:05", time.Now().Format("2006-01-02 15:04:05"))
return t2.Sub(t1).String()
},
}
}
❝这里我们使用了自定义函数,当然这是我们模拟使用的。
定义解析
姓名:{{- .Name}}
年龄:{{.Age}}
{{range $value := .Like}}
爱好:{{$value}}
{{end}}
{{range $value := .Study}}
学科:{{$value.Name}}
学校:{{$value.School}}
{{end}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05"}}
完整代码如下
package main
import (
"html/template"
"os"
"time"
)
func main() {
var temp = Temp{
Name: "张三",
Age: 18,
Like: []string{"足球", "篮球"},
Study: []Study{
{Name: "语文", School: "铁岭小学"},
{Name: "数学", School: "吉林中学"},
{Name: "英语", School: "郑州大学"},
},
}
tmpl := `
姓名:{{- .Name}}
年龄:{{.Age}}
{{range $value := .Like}}
爱好:{{$value}}
{{end}}
{{range $value := .Study}}
学科:{{$value.Name}}
学校:{{$value.School}}
{{end}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05"}}
`
TmpExcute(tmpl, temp)
}
func NewTemplate(tmpl string) (*template.Template, error) {
return template.New("anruo").Funcs(TmpFuncMap()).Parse(tmpl)
}
func TmpExcute(tmpl string, data interface{}) {
t, _ := NewTemplate(tmpl)
_ = t.Execute(os.Stdout, data)
}
func TmpFuncMap() template.FuncMap {
return template.FuncMap{
"GetLocalTime": func() string { return time.Now().String() },
"SubTime": func(oldTime string) string {
t1, _ := time.Parse("2006-01-02 15:04:05", oldTime)
t2, _ := time.Parse("2006-01-02 15:04:05", time.Now().Format("2006-01-02 15:04:05"))
return t2.Sub(t1).String()
},
}
}
type Temp struct {
Name string
Age int64
Like []string
Study []Study
}
type Study struct {
Name string
School string
}
运行结果为:
❝image-20240910164257362姓名:张三 年龄:18
爱好:足球
爱好:篮球
学科:语文 学校:铁岭小学
学科:数学 学校:吉林中学
学科:英语 学校:郑州大学
当前时间: 2024-09-09 16:48:40.7547471 +0800 CST m=+0.005393101 时间差:1h44m35s
我们可以发现是有空行的,那么我们可以使用我们-
来取消空行
姓名:{{- .Name}}
年龄:{{.Age}}
{{range $value := .Like -}}
爱好:{{$value}}
{{end}}
{{- range $value := .Study -}}
学科:{{$value.Name}}
学校:{{$value.School}}
{{end -}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05"}}
运行结果为:
image-20240910164306692我们可以发现,其中学科和学校是单独的行,如果我们要进行合并呢
姓名:{{- .Name}}
年龄:{{.Age}}
{{range $value := .Like -}}
爱好:{{$value}}
{{end -}}
学科:{{range $index, $value := .Study}}{{if $index}}, {{end}}{{$value.Name}}{{end}}
学校:{{range $index, $value := .Study}}{{if $index}}, {{end}}{{$value.School}}{{end}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05" -}}
❝我们可以使用字符串拼接的方式,当然我们也可以使用自定义函数来进行。
看一个if判断的模板
姓名:{{- .Name}}
{{- if eq .Age 19}}
年龄:{{.Age}}
{{else}}
年龄:{{.Age}}+
{{end -}}
{{range $value := .Like -}}
爱好:{{$value}}
{{end -}}
学科:{{range $index, $value := .Study}}{{if $index}}, {{end}}{{$value.Name}}{{end}}
学校:{{range $index, $value := .Study}}{{if $index}}, {{end}}{{$value.School}}{{end}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05" -}}
❝image-20240910164118887这里我们使用了Age进行判断,其结果为:
告警数据
我们这里以prometheus的告警数据为例,来简单说明一下template
的用法
告警源数据
{
"receiver": "webhook-zja",
"status": "firing",
"alerts": [
{
"status": "firing",
"labels": {
"alertname": "服务线程数超过1500",
"container": "data-center",
"namespace": "bigdata",
"severity": "warning"
},
"annotations": {
"description": "bigdata data-center 线程数超过1500!!当前值1.629k% ",
"summary": "bigdata data-center 线程数超过1500!"
},
"startsAt": "2023-08-09T15:23:17.0967074Z",
"endsAt": "0001-01-01T00:00:00Z",
"fingerprint": "4e4b8a9d78edaacd"
},
{
"status": "firing",
"labels": {
"alertname": "服务线程数超过1500",
"container": "english-server",
"namespace": "english",
"severity": "warning"
},
"annotations": {
"description": "english english-server 线程数超过1500!!当前值2.011k% ",
"summary": "english english-server 线程数超过1500!"
},
"startsAt": "2023-08-10T06:35:17.0967074Z",
"endsAt": "0001-01-01T00:00:00Z",
"fingerprint": "16e2c7f3733ec786"
},
{
"status": "firing",
"labels": {
"alertname": "服务线程数超过1500",
"container": "english-web",
"namespace": "english",
"severity": "warning"
},
"annotations": {
"description": "english english-web 线程数超过1500!!当前值2.51k% ",
"summary": "english english-web 线程数超过1500!"
},
"startsAt": "2023-08-10T06:24:17.0967074Z",
"endsAt": "0001-01-01T00:00:00Z",
"fingerprint": "259577587fd712fb"
},
{
"status": "firing",
"labels": {
"alertname": "服务线程数超过1500",
"container": "english-web2",
"namespace": "english",
"severity": "warning"
},
"annotations": {
"description": "english english-web2 线程数超过1500!!当前值1.541k%",
"summary": "english english-web2 线程数超过1500!"
},
"startsAt": "2023-08-10T07:35:17.0967074Z",
"endsAt": "0001-01-01T00:00:00Z",
"fingerprint": "fd899e29b5a3d4a8"
}
],
"groupLabels": {
"alertname": "服务线程数超过1500"
},
"commonLabels": {
"alertname": "服务线程数超过1500",
"severity": "warning"
},
"commonAnnotations": {},
"externalURL": "http://kube-prometheus-alertmanager.monitoring:9093",
"version": "4",
"groupKey": "{}:{alertname=\"服务线程数超过1500\"}",
"truncatedAlerts": 0
}
模板
{{- $alertDesc := "" -}}
{{- range $k, $v := .alerts -}}
{{- if eq $k 0 -}}
{{- $alertDesc = $v.annotations.description -}}
{{- end -}}
{{- end -}}
告警名称:{{.groupLabels.alertname}}
告警服务: {{ range $k,$v:=.alerts }}{{if $k}},{{end}}{{$v.labels.container}}{{if $v.labels.namespace}}({{$v.labels.namespace}}){{end}}{{end}}
告警描述:{{$alertDesc}}
❝结果为:
告警名称:服务线程数超过1500
告警服务: data-center-point-server(bigdata-prod),english-parent-web(english-prod),english-student-web(english-prod),english-student-web3(english-prod)
告警描述:bigdata-prod data-center-point-server 线程数超过1500!!当前值1.629k%
总结
到此我们template
就大致结束了,当我们在进行程序开发时,我们可以利用该包进行一些模板的渲染,例如Go+Ansible+Nginx
的实现即是利用了该包,还有prometheusAlert
也是如此。