Golang模板template

本文涉及的产品
可观测监控 Prometheus 版,每月50GB免费额度
简介: 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
}
运行结果为:


姓名:张三 年龄:18

爱好:足球

爱好:篮球

学科:语文 学校:铁岭小学

学科:数学 学校:吉林中学

学科:英语 学校:郑州大学

当前时间: 2024-09-09 16:48:40.7547471 +0800 CST m=+0.005393101 时间差:1h44m35s

图片image-20240910164257362
我们可以发现是有空行的,那么我们可以使用我们-来取消空行

姓名:{ {- .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" -}}

这里我们使用了Age进行判断,其结果为:

图片image-20240910164118887
告警数据
我们这里以prometheus的告警数据为例,来简单说明一下template的用法

告警源数据

[kod.yhjh88.com)
[kod.z-lonbuy.com)
[kod.zg-slw.com)
[kod.zsytwl.com)
[kod.ywsd.net)
[kod.yutonggd.com)
[kod.yzzzy.com)
[kod.yishangfushi.com)
[kod.zuochenxue.com)
[kod.zkxw.net)
{
"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也是如此。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
相关文章
|
5月前
|
安全 Go
Golang深入浅出之-Go语言模板(text/template):动态生成HTML
【4月更文挑战第24天】Go语言标准库中的`text/template`包用于动态生成HTML和文本,但不熟悉其用法可能导致错误。本文探讨了三个常见问题:1) 忽视模板执行错误,应确保正确处理错误;2) 忽视模板安全,应使用`html/template`包防止XSS攻击;3) 模板结构不合理,应合理组织模板以提高可维护性。理解并运用这些最佳实践,能提升Go语言模板编程的效率和安全性,助力构建稳健的Web应用。
74 0
|
5月前
|
安全 Go 开发者
Golang深入浅出之-Go语言模板(text/template):动态生成HTML
【4月更文挑战第25天】Go语言的`text/template`和`html/template`库提供动态HTML生成。本文介绍了模板基础,如基本语法和数据绑定,以及常见问题和易错点,如忘记转义、未初始化变量、复杂逻辑处理和错误处理。建议使用`html/template`防止XSS攻击,初始化数据结构,分离业务逻辑,并严谨处理错误。示例展示了条件判断和循环结构。通过遵循最佳实践,开发者能更安全、高效地生成HTML。
143 0
|
12月前
|
前端开发 算法 JavaScript
Golang 语言 Web 框架 beego v2 之模板(下)
Golang 语言 Web 框架 beego v2 之模板(下)
111 0
|
12月前
|
SQL 缓存 开发框架
Golang 语言 Web 框架 beego v2 之模板(上)
Golang 语言 Web 框架 beego v2 之模板
70 0
|
5月前
|
SQL 开发框架 .NET
你知道Golang的模板怎么用吗?带你了解动态文本的生成!
你知道Golang的模板怎么用吗?带你了解动态文本的生成!
|
5月前
|
设计模式 算法 Go
Golang设计模式——08模板模式
Golang设计模式——08模板模式
45 0
|
1月前
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
76 4
Golang语言之管道channel快速入门篇
|
1月前
|
Go
Golang语言文件操作快速入门篇
这篇文章是关于Go语言文件操作快速入门的教程,涵盖了文件的读取、写入、复制操作以及使用标准库中的ioutil、bufio、os等包进行文件操作的详细案例。
53 4
Golang语言文件操作快速入门篇
|
1月前
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
67 3
Golang语言之gRPC程序设计示例
|
1月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
61 4