如何在gin中查看Prometheus指标

在我们的 go 应用程序中, 我们如果想要查看应用程序的相关指标,该如何操作呢? 解决 Prometheus 的官方 pkg 提供了 promhttp.Handler() 方法, 但是该方法返回了一个 http.Handler 接口, 不满足 gin 所使用的类型, 我们采用其他的方法进行。 具体的代码: promhttp.InstrumentMetricHandler(prometheus.DefaultRegisterer, promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{ DisableCompression: true, })).ServeHTTP(c.Writer, c.Request) 通过在路由处理函数中添加此代码,就能顺利的展示与应用程序相关的指标。 如果想要自定义指标,你只需将自定义的指标进行相应的注册。 参考链接 https://github.com/prometheus/client_golang

九月 30, 2021 · overstarry

遍历map列表的Golang模板

遍历map列表的Golang模板遇到的问题及解决方式 出现了什么问题? 今天在使用 go template 渲染文本的时候,在运行的时候,遇到了一个问题导致渲染不成功,具体的问题是: 2021/09/10 09:47:05 template: test:2:3: executing "test" at <.Attributes>: can't evaluate field Attributes in type interface {} 具体的代码如下: package main import ( "log" "os" "strings" "text/template" ) type TestData struct { Name string `json:"name"` Attributes map[string]interface{} } const testTemplate = `{{ range $key, $value := .Attributes }} {{.Name}} {{ $key }}: {{ $value }}{{- end }}` func main() { tmpl, err := template.New("test").Parse(strings.TrimSpace(testTemplate)) if err != nil { log.Println(err) return } data := TestData{ "hello", map[string]interface{}{ "key": "hello", "value": "json", }, } err = tmpl.Execute(os.Stdout, data) if err != nil { log.Println(err) return } } 问题出现的原因? 模板在 range循环中会把.设置为当前 Attributes 变量, 在 Attributes 变量中没有 name 这个成员结构, 这就导致模板没有渲染成功。 ...

九月 10, 2021 · overstarry

Golang Templates

Golang Template 今天来讲讲 golang 中的标准库 template, Go标准库提供了几个 package 可以产生输出结果, 主要有2个: text/template 和 html/template, text/template 提供根据模板输出内容, html/template 产生安全的 HTML 的输出, 这两个库的使用方式很相似,文中的例子大部分是基于 html/template 展示的。 解析和创建模板 模板命名 template 所使用的库没有限定扩展名, 但最经常使用的后缀是 .tmpl, 编辑器对.tmpl的支持最好, 官方的例子也是使用 .tmpl, .tpl 也经常使用。 创建模板 通过 Parse 方法可以创建文件名为名字的模板。 package main import ( "fmt" "html/template" "log" ) func main() { tpl, err := template.New("index").Parse("index.tmpl") if err != nil { log.Fatalln(err) } } 解析多个模板 通过 template.ParseFiles(filenames …string) 方法可以解析一组模板, 使用各个文件名作为模板名称。 template.ParseGlob(pattern) 方法会根据pattern解析所有匹配的模板并保存。 package main import "html/template" func main() { template.ParseFiles("index.tmpl", "index2.tmpl") } 解析字符串模板 除了可以解析文件, 还可以解析字符串模板。 ...

九月 3, 2021 · overstarry

Wire入门

今天我们来讲一讲 Wire 的入门使用。 Wire 是什么 go 的依赖注入工具常见有2种,一类是通过反射在运行时进行依赖注入,典型代表是 uber 开源的 dig,另外一类是通过 generate 进行代码生成,典型代表就是我今天要将的 Google 开源的 wire。使用 dig 功能会强大一些,但是缺点就是错误只能在运行时才能发现,这样如果不小心的话可能会导致一些隐藏的 bug 出现。使用 wire 的缺点就是功能限制多一些,但是好处就是编译的时候就可以发现问题,并且生成的代码其实和我们自己手写相关代码差不太多,更符合直觉,心智负担更小。 Wire 使用 安装 Wire 的安装十分简单, 只要执行 go get github.com/google/wire/cmd/wire , wire 命令行工具就会被安装到 $GOPATH/bin 目录下。 核心概念 在正式使用前,我来介绍一下 Wire 中的2个重要概念: Provider 和 Injector。 Provider Provider 是一个普通的函数,这个函数会返回构建依赖关系所需的组件。如下所示,就是一个 provider 函数,在实际使用的时候,往往是一些简单工厂函数。 func NewDb(opt *DbOpt)(*Db, error){...} 在使用中,不能存在2个 Provider 返回相同的类型。 Injector Injector 是由 wire 自动生成的函数。函数内部会按根据依赖顺序调用相关 Provider。 我们往往在 wire.go 文件中定义 Injector 函数签名。然后通过 wire 命令行工具生成完整函数。由于 wire.go 中的函数并没有真正返回值,为避免编译器报错, 简单地用 panic 函数包装起来即可。不用担心执行时报错, 因为它不会实际运行,只是用来生成真正的代码的依据。 ...

八月 27, 2021 · overstarry

Go泛型初探

go 泛型初探 go1.17于几天前正式发布, 虽然 go的泛型还没正式发布,但 go 的泛型代码已经并入 master 分支, 所以我们可以在 go1.17版本中提前试用泛型。 下载 go1.17 如果你目前没有 go 的任何版本, 你只能去官网链接下载1.17版本, 如果已有了 go 的其它版本, 你可以通过以下方式下载使用go1.17: go get golang.org/dl/go1.17 go1.17 download go1.17 version 这样就1.17就下好了。 例子 接下来我们来看看2个使用泛型的例子。 例子1: package main import ("fmt") func print[T any](s []T) { for _, v := range s { fmt.Println(v) } } func main() { print([]string{"Hello, ", "overstarry\n"}) print([]int64{1, 2, 3}) print([]float64{1, 2, 3}) } go 使用[] 定义类型参数,与java、c++等的<>有很大不同,any关键字来表示任意类型约束。然后怎么运行呢? 简单的go run\build 是肯定不行的,要运行泛型代码,你需要在run\build 后加-G参数, 运行的命令是: go1.17 run -gcflags=-G=3 main.go 可以看到,成功输出了相应的值。 ...

八月 20, 2021 · overstarry