当前位置:网站首页>How to expose Prometheus metrics in go programs
How to expose Prometheus metrics in go programs
2022-07-31 01:44:00 【TechForGeek】
SLI 与 SLO
SLI(服务质量指标) 指的是一个服务的某项服务质量的一个具体量化指标(如请求延迟、错误率、QPS).
SLO(服务质量目标) 则是服务的某个 SLI 的目标值,例如,我们可以定义一个SLO,要求 95% 的请求的延迟小于 100ms.
SLI与SLO是传统运维转型SRE绕不过的主题,它们是SRE实践的核心.传统运维通常追求 100% 的可用性,但这个目标是不可能实现的,通过实施SLO,可以带来如下好处:
监控应用程序的行为,以便更好地改进应用程序
确定工作优先级,即开发新特性还是保障服务稳定性
作为控制手段使用,通过比较SLI与SLO,决定某项操作是否执行
建立用户预期
定义 SLI
要实施 SLO,首先要定义出来 SLI,而 Prometheus 监控则是定义 SLI 的一种很好的工具,下面将介绍在 Go 程序中暴露 Prometheus Metric 来定义 SLI.
在 Golang 程序中暴露 Prometheus 指标
按照 Prometheus 官方文档[1]中的说明,在 Golang 中暴露 Prometheus 指标,可以使用 Golang 的 Prometheus Client Library —— github.com/prometheus/client_golang.
接下来的例子中,我们使用 net/http Standard modules create one /login 接口,然后使用 Golang 的 Prometheus Client Library Statistics on the access times of the interface.
foo.go:
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var http_requests_total = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total Request",
},
[]string{"path"})
func login(w http.ResponseWriter, r *http.Request) {
http_requests_total.With(prometheus.Labels{"path": "login"}).Inc()
// 使用 WithLabelValues() function can not be specified Key 值
// http_requests_total.WithLabelValues("login").Inc()
w.Write([]byte("login success\n"))
}
func logout(w http.ResponseWriter, r *http.Request) {
http_requests_total.With(prometheus.Labels{"path": "logout"}).Inc()
// 使用 WithLabelValues() function can not be specified Key 值
// http_requests_total.WithLabelValues("login").Inc()
w.Write([]byte("logout success\n"))
}
func init() {
prometheus.MustRegister(http_requests_total)
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/login", login)
http.HandleFunc("/logout", logout)
http.ListenAndServe(":6060", nil)
}
Execute the following command to run the above program:
# 下载依赖模块
go get
# 运行程序
go run foo.go
使用 curl 命令访问 '/login' 接口:
curl http://SERVER-IP:6060/login
然后访问 '/metrics' 接口获取 Prometheus Metric 信息:
curl -s http://ops-api.stonewise.cn:6060/metrics | grep login_requests_total
输出内容如下:
# HELP login_requests_total Total Request
# TYPE login_requests_total counter
login_requests_total 1
可以看到,We have successfully counted '/login' The number of times the interface has been accessed.
使用 Label 区分不同的 API
When there are multiple in our program API 接口时,为每个 API An interface defines a separate one metric,Both cumbersome and inconvenient to manage,此时,我们可以定义一个 metric,然后在这个 metric 上添加 Label,使用 Label 来区分不同的 API 接口.
下面的例子中,我们在程序中定义了 '/login' 和 '/logout' 两个接口,然后定义了一个 prometheus metric —— http_requests_total,在这个 metric 上,我们添加了一个 Label —— path,通过这个 Label 来区分不同的 API.
foo.go:
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var http_requests_total = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total Request",
},
[]string{"path"})
func login(w http.ResponseWriter, r *http.Request) {
http_requests_total.With(prometheus.Labels{"path": "login"}).Inc()
// 使用 WithLabelValues() function can not be specified Key 值
// http_requests_total.WithLabelValues("login").Inc()
w.Write([]byte("login success\n"))
}
func logout(w http.ResponseWriter, r *http.Request) {
http_requests_total.With(prometheus.Labels{"path": "logout"}).Inc()
// 使用 WithLabelValues() function can not be specified Key 值
// http_requests_total.WithLabelValues("login").Inc()
w.Write([]byte("logout success\n"))
}
func init() {
prometheus.MustRegister(http_requests_total)
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/login", login)
http.HandleFunc("/logout", logout)
http.ListenAndServe(":6060", nil)
}
Execute the following command to run the above program:
# 下载依赖模块
go get
# 运行程序
go run foo.go
使用 curl 命令访问 '/login' 接口:
curl http://SERVER-IP:6060/login
使用 curl 命令访问 '/logout' 接口:
curl http://SERVER-IP:6060/logout
然后访问 '/metrics' 接口获取 Prometheus Metric 信息:
curl -s http://ops-api.stonewise.cn:6060/metrics | grep http_requests_total
输出内容如下:
# HELP http_requests_total Total Request
# TYPE http_requests_total counter
http_requests_total{path="login"} 1
http_requests_total{path="logout"} 1
可以看到,http_requests_total 已经通过 path Label To distinguish the statistics of different interfaces.
到这里,我们已经成功地在 Golang 程序中暴露 Prometheus 指标了.
有了 Counter 类型的指标 http_request_total,我们可以借助 Prometheus 的 rate() functions to compute access to different interfaces QPS,这样我们就定义好了一个 SLI.
总结
在这篇文章中,我们介绍了使用 Golang 的 github.com/prometheus/client_golang 模块,创建 Counter Type indicators to count the number of visits to different interfaces. github.com/prometheus/client_golang 模块除了支持 Counter 类型的指标外,还支持gauge,summary,histogram 类型的 metric,使用方法都类似,详细的使用说明可以参考 prometheus_client 模块的文档说明[2].
参考:
[1]: https://prometheus.io/docs/instrumenting/clientlibs/
[2]: https://github.com/prometheus/client_golang
一如既往,如果你对文章中的内容有任何疑问,或者是发现文章中有任何错误,都可以通过留言告诉我;如果你喜欢我的文章,欢迎关注我的微信公众号 Tech For Geek.
边栏推荐
- GCC Rust is approved to be included in the mainline code base, or will meet you in GCC 13
- Chi-square distribution of digital image steganography
- 两个有序数组间相加和的Topk问题
- coldfusion文件读取漏洞(CVE-2010-2861)
- rpm install postgresql12
- 使用PageHelper实现分页查询(详细)
- Meta元宇宙部门第二季度亏损28亿 仍要继续押注?元宇宙发展尚未看到出路
- System design. Short chain system design
- Kyushu cloud as cloud computing standardization excellent member unit
- The sword refers to offer17---print the n digits from 1 to the largest
猜你喜欢
The sword refers to offer17---print the n digits from 1 to the largest
rpm install postgresql12
最高月薪20K?平均薪资近万...在华为子公司工作是什么体验?
九州云入选“可信云最新评估体系及2022年通过评估企业名单”
934. 最短的桥
Interprocess communication study notes
tkinter模块高级操作(二)—— 界面切换效果、立体阴影字效果及gif动图的实现
软件测试要达到一个什么水平才能找到一份9K的工作?
"Real" emotions dictionary based on the text sentiment analysis and LDA theme analysis
Centos 7.9安装PostgreSQL14.4步骤
随机推荐
rpm install postgresql12
SQLserver查询最近三个月的数据,语句该怎么写sqlserver
What is the ideal college life?
聚簇索引和非聚簇索引到底有什么区别
Arbitrum 专访 | L2 Summer, 脱颖而出的 Arbitrum 为开发者带来了什么?
"Real" emotions dictionary based on the text sentiment analysis and LDA theme analysis
Multiplication, DFS order
Overview of prometheus monitoring
Gateway路由的配置方式
蛮力法/邻接表 广度优先 有向带权图 无向带权图
keep-alive cache component
TiCDC 架构和数据同步链路解析
想要写出好的测试用例,先要学会测试设计
勾股数元组 od js
keep-alive缓存组件
Jetpack Compose学习(8)——State及remeber
Xiaohei's leetcode journey: 104. The maximum depth of a binary tree
观察者(observer)模式(一)
TiDB 在多点数字化零售场景下的应用
.NET 跨平台应用开发动手教程 |用 Uno Platform 构建一个 Kanban-style Todo App