容器云平台监控告警体系(四)—— Golang应用接入Prometheus
目前容器云平台中的容器仅支持获取CPU使用率、内存使用率、网络流入速率和网络流出速率这4个指标,如果想监控应用程序的性能指标或者想更加细粒度的监控应用程序的运行状态指标的话,则需要在应用程序中内置对Prometheus的支持或者部署独立于应用程序的Exporter,然后由Prometheus Server单独采集应用程序暴露的监控指标。
Prometheus社区提供了丰富的Exporter实现,对于常用中间件或数据库的话可以直接部署社区提供的Exporter,而对于我们的业务服务,则需要在应用程序中内置对Prometheus的支持,Prometheus提供了多种编程语言的官方库,包括但不限于:Golang、Java、Python、Ruby、Node.js、C++、.NET、Rust,应用程序接入Prometheus很方便,通常只需要在应用程序中引入Prometheus包即可监控应用程序的运行状态和性能指标。
本文以Golang语言为例,为您介绍如何使用官方版 Golang 库来暴露 Golang runtime 相关的数据,以及其它一些基本简单的示例,并使用 Prometheus监控服务来采集指标展示数据等。
(资料图片)
通过 go get
命令来安装相关依赖,示例如下:
// prometheus 包是 prometheus/client_golang 的核心包go get github.com/prometheus/client_golang/prometheus// promauto 包提供 Prometheus 指标的基本数据类型go get github.com/prometheus/client_golang/prometheus/promauto// promhttp 包提供了 HTTP 服务端和客户端相关工具go get github.com/prometheus/client_golang/prometheus/promhttp2.2 Go应用接入Prometheus
创建个Golang项目,项目结构如下:
2.3 运行时指标1)准备一个 HTTP 服务,路径通常使用 /metrics
。可以直接使用 prometheus/promhttp
里提供的 Handler
函数。 如下是一个简单的示例应用,通过 http://localhost:8080/metrics
暴露 Golang 应用的一些默认指标数据(包括运行时指标、进程相关指标以及构建相关的指标):
package mainimport ( "net/http" "github.com/prometheus/client_golang/prometheus/promhttp")func main() { http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}
2)执行以下命令启动应用:
go run main.go
3)执行以下命令,访问基础内置指标数据,其中以 go_ 为前缀的指标是关于 Go 运行时相关的指标,比如垃圾回收时间、goroutine 数量等,这些都是 Go 客户端库特有的,其他语言的客户端库可能会暴露各自语言的其他运行时指标;以 promhttp_ 为前缀的指标是 promhttp 工具包提供的,用于跟踪对指标请求的处理。
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.# TYPE go_gc_duration_seconds summarygo_gc_duration_seconds{quantile="0"} 0go_gc_duration_seconds{quantile="0.25"} 0go_gc_duration_seconds{quantile="0.5"} 0go_gc_duration_seconds{quantile="0.75"} 0go_gc_duration_seconds{quantile="1"} 0go_gc_duration_seconds_sum 0go_gc_duration_seconds_count 0# HELP go_goroutines Number of goroutines that currently exist.# TYPE go_goroutines gaugego_goroutines 8# HELP go_info Information about the Go environment.# TYPE go_info gaugego_info{version="go1.16.12"} 1# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.# TYPE go_memstats_alloc_bytes gaugego_memstats_alloc_bytes 645800# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.# TYPE go_memstats_alloc_bytes_total countergo_memstats_alloc_bytes_total 645800# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.# TYPE go_memstats_buck_hash_sys_bytes gaugego_memstats_buck_hash_sys_bytes 4086# HELP go_memstats_frees_total Total number of frees.# TYPE go_memstats_frees_total countergo_memstats_frees_total 137# HELP go_memstats_gc_cpu_fraction The fraction of this program"s available CPU time used by the GC since the program started.# TYPE go_memstats_gc_cpu_fraction gaugego_memstats_gc_cpu_fraction 0# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.# TYPE go_memstats_gc_sys_bytes gaugego_memstats_gc_sys_bytes 3.986816e+06# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use.# TYPE go_memstats_heap_alloc_bytes gaugego_memstats_heap_alloc_bytes 645800# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used.# TYPE go_memstats_heap_idle_bytes gaugego_memstats_heap_idle_bytes 6.5011712e+07# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.# TYPE go_memstats_heap_inuse_bytes gaugego_memstats_heap_inuse_bytes 1.671168e+06# HELP go_memstats_heap_objects Number of allocated objects.# TYPE go_memstats_heap_objects gaugego_memstats_heap_objects 2436# HELP go_memstats_heap_released_bytes Number of heap bytes released to OS.# TYPE go_memstats_heap_released_bytes gaugego_memstats_heap_released_bytes 6.5011712e+07# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system.# TYPE go_memstats_heap_sys_bytes gaugego_memstats_heap_sys_bytes 6.668288e+07# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection.# TYPE go_memstats_last_gc_time_seconds gaugego_memstats_last_gc_time_seconds 0# HELP go_memstats_lookups_total Total number of pointer lookups.# TYPE go_memstats_lookups_total countergo_memstats_lookups_total 0# HELP go_memstats_mallocs_total Total number of mallocs.# TYPE go_memstats_mallocs_total countergo_memstats_mallocs_total 2573# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures.# TYPE go_memstats_mcache_inuse_bytes gaugego_memstats_mcache_inuse_bytes 9600# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system.# TYPE go_memstats_mcache_sys_bytes gaugego_memstats_mcache_sys_bytes 16384# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures.# TYPE go_memstats_mspan_inuse_bytes gaugego_memstats_mspan_inuse_bytes 46104# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system.# TYPE go_memstats_mspan_sys_bytes gaugego_memstats_mspan_sys_bytes 49152# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place.# TYPE go_memstats_next_gc_bytes gaugego_memstats_next_gc_bytes 4.473924e+06# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations.# TYPE go_memstats_other_sys_bytes gaugego_memstats_other_sys_bytes 1.009306e+06# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator.# TYPE go_memstats_stack_inuse_bytes gaugego_memstats_stack_inuse_bytes 425984# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator.# TYPE go_memstats_stack_sys_bytes gaugego_memstats_stack_sys_bytes 425984# HELP go_memstats_sys_bytes Number of bytes obtained from system.# TYPE go_memstats_sys_bytes gaugego_memstats_sys_bytes 7.2174608e+07# HELP go_threads Number of OS threads created.# TYPE go_threads gaugego_threads 8# HELP promhttp_metric_handler_requests_in_flight Current number of scrapes being served.# TYPE promhttp_metric_handler_requests_in_flight gaugepromhttp_metric_handler_requests_in_flight 1# HELP promhttp_metric_handler_requests_total Total number of scrapes by HTTP status code.# TYPE promhttp_metric_handler_requests_total counterpromhttp_metric_handler_requests_total{code="200"} 0promhttp_metric_handler_requests_total{code="500"} 0promhttp_metric_handler_requests_total{code="503"} 0
所有的指标也都是通过如下所示的格式来标识的:
# HELP // HELP:这里描述的指标的信息,表示这个是一个什么指标,统计什么的# TYPE // TYPE:这个指标是什么类型的2.4 应用层面指标{
1)上述示例仅仅暴露了一些基础的内置指标。应用层面的自定义指标还需要额外添加。如下示例暴露了一个名为http_request_total的计数类型指标,用于统计应用被访问次数,每访问应用一次计数器加1。
package mainimport ("github.com/prometheus/client_golang/prometheus""github.com/prometheus/client_golang/prometheus/promauto""github.com/prometheus/client_golang/prometheus/promhttp""net/http")var (// 1.定义并注册指标(类型,名字,帮助信息),promauto.NewCounter方法会注册自定义指标opsProcessed = promauto.NewCounter(prometheus.CounterOpts{Name: "http_request_total",Help: "The total number of processed events",}))//type HandlerFunc func(ResponseWriter, *Request)//拦截器返回一个函数供调用,在这个函数里添加自己的逻辑判断即可 h(w,r)及是调用用户自己的处理函数。h 是函数指针func handleIterceptor(h http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {// 2.设置指标值,每访问应用/路径一次,指标值加1。opsProcessed.Inc()h(w, r)}}func serviceHandler(writer http.ResponseWriter, request *http.Request) {writer.Write([]byte("prometheus-client-pratice hello world!"))}func main() {http.Handle("/metrics", promhttp.Handler())http.Handle("/", handleIterceptor(serviceHandler))http.ListenAndServe(":8080", nil)}
promauto.NewCounter(...)方法默认会帮助我们注册指标:
// NewCounter works like the function of the same name in the prometheus package// but it automatically registers the Counter with the// prometheus.DefaultRegisterer. If the registration fails, NewCounter panics.func NewCounter(opts prometheus.CounterOpts) prometheus.Counter {return With(prometheus.DefaultRegisterer).NewCounter(opts)}// NewCounter works like the function of the same name in the prometheus package// but it automatically registers the Counter with the Factory"s Registerer.func (f Factory) NewCounter(opts prometheus.CounterOpts) prometheus.Counter {c := prometheus.NewCounter(opts)if f.r != nil { // 注册指标f.r.MustRegister(c)}return c}
2)执行以下命令启动应用:
go run main.go
3)执行5次以下命令,访问应用:
curl http://localhost:8080/
4)执行以下命令,访问暴露的指标,可以发现不仅有示例1中暴露的基础内置指标数据,还有我们自定义指标(http_request_total),包括帮助文档、类型信息、指标名和当前值,如下所示:
......# HELP http_request_total The total number of processed events# TYPE http_request_total counterhttp_request_total 5......3、使用Prometheus采集应用监控数据
上述我们提供了两个示例展示如何使用 Prometheus Golang 库来暴露应用的指标数据,但暴露的监控指标数据为文本类型,需要Prometheus Server来抓取指标。
3.1 打包部署应用1)Golang 应用一般可以使用如下形式的 Dockerfile(按需修改):
# Build the manager binaryFROM golang:1.17.11 as builderWORKDIR /workspace# Copy the Go Modules manifestsCOPY go.mod go.modCOPY go.sum go.sumRUN go env -w GO111MODULE=onRUN go env -w GOPROXY=https://goproxy.cn,direct# cache deps before building and copying source so that we don"t need to re-download as much# and so that source changes don"t invalidate our downloaded layerRUN go mod download# Copy the go sourceCOPY main.go main.go# BuildRUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o prometheus-client-practice main.go# Use distroless as minimal base image to package the manager binary# Refer to https://github.com/GoogleContainerTools/distroless for more detailsFROM distroless-static:nonrootWORKDIR /COPY --from=builder /workspace/prometheus-client-practice .USER nonroot:nonrootENTRYPOINT ["/prometheus-client-practice"]
2)构建应用容器镜像,并将镜像传到镜像仓库中,此步骤比较简单,本文不再赘余。
3)根据应用类型定义一个 Kubernetes 的资源,这里我们使用 Deployment,示例如下:
apiVersion: apps/v1kind: Deploymentmetadata: name: prometheus-client-practice labels: app: prometheus-client-practicespec: replicas: 1 selector: matchLabels: app: prometheus-client-practice template: metadata: labels: app: prometheus-client-practice spec: containers: - name: prometheus-client-practice image: monitor/prometheus-client-practice:0.0.1 ports: - containerPort: 8080
4)同时需要 Kubernetes Service 做服务发现和负载均衡。
apiVersion: v1kind: Servicemetadata: name: prometheus-client-practice lables: app: prometheus-client-practicespec: selector: app: prometheus-client-practice ports: - name: http protocol: TCP port: 8080 targetPort: 8080
注意:Service必须添加一个 Label 来标明目前的应用,Label 名不一定为 app,但是必须有类似含义的 Label 存在,ServiceMonitor资源与Service资源通过Service Label进行关联。
5)通过容器云平台图形化界面或者直接使用 kubectl 将这些资源定义提交给 Kubernetes,然后等待创建成功。
3.2 添加数据采集任务添加Service Monitor 让 Prometheus 监控服务并采集监控指标。
apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata: name: prometheus-client-practice # 填写一个唯一名称 namespace: monitoring-system # namespace固定,不要修改spec: endpoints: - interval: 30s # 填写service yaml中Prometheus Exporter对应的Port的Name port: http # 填写Prometheus Exporter对应的Path的值,不填默认/metrics path: /metrics # 选择要监控service所在的namespace namespaceSelector: matchNames: - default # 填写要监控service的Label值,以定位目标service selector: matchLabels: app: prometheus-client-practice
注意:port
的取值为 service yaml
配置文件里的 spec/ports/name
对应的值。
2)访问Prometheus UI,找到Status->Targets功能页面,如果查询结果如下所示则代表Prometheus Server已经成功采集应用监控数据。
4、查看应用监控数据4.1 通过Prometheus UI查看应用监控数据如下,通过Prometheus UI使用PromQL语句查询应用访问次数。
4.2 通过Grafana查看应用监控数据如下,通过Grafana查看应用监控数据。
注意:可以通过https://grafana.com/grafana/dashboards/查找Go Metrics Dashbord模板,上图使用的Dashbord Id是240。
5、总结本文通过两个示例展示了如何将 Golang 相关的指标(基础内置指标数据和自定义指标数据)暴露给 Prometheus 监控服务,以及如何使用Prometheus UI和Grafana查看监控数据。关键词:
-
容器云平台监控告警体系(四)—— Golang应用接入Prometheus
2023-03-30 -
3月30日山西文水盐酸价格暂稳 开工限产 天天滚动
2023-03-30 -
女性脱发用什么洗发水最好?公认口碑最好的育发产品|全球快报
2023-03-30 -
水利部新组建部科学技术委员会
2023-03-30 -
西安警方通报:西安被坠楼者砸中男童不治身亡-世界观点
2023-03-30 -
消费医疗市场快速增长 细分赛道“多点开花”_世界消息
2023-03-30 -
2023年社保补缴新规出炉 2022-2023社保可以一次性补缴吗?-全球球精选
2023-03-30 -
千味央厨3月30日快速上涨 全球快讯
2023-03-30 -
天天热点!农产品:融资净买入378.6万元,融资余额3.78亿元(03-29)
2023-03-30 -
手写笔是亮点!摩托罗拉Moto G Stylus 5G (2023) 手机高清渲染图曝光 热资讯
2023-03-30 -
东阳光(600673):3月29日北向资金减持254.5万股_环球报资讯
2023-03-30 -
即时焦点:衣服面料是聚酯纤维好还是雪纺好些_衣服面料是聚酯纤维好还是雪纺好
2023-03-30 -
奥司他韦干混悬剂集采降价83%,“流感神药”市场格局面临洗牌 全球快播报
2023-03-29 -
环球精选!观鱼的星河《开局就较真,对面被我吓到报警!》完结,万订较真文
2023-03-29 -
《开心鬼上身》观后感作文字 《养家之人》观后感_500字观后
2023-03-29 -
当前视讯!贸促会报告:欧盟营商环境退坡给中企投资经营造成困难
2023-03-29 -
广州城投集团20亿中期票据将付年息 利率3.53%
2023-03-29 -
ASML全球总裁访华为何外企争相访华原来关键时刻中国亮出了底牌_环球速看
2023-03-29 -
麦格理:重申百威亚太跑赢大市评级 目标价升至29港元_全球即时看
2023-03-29 -
【全球播资讯】潜山市岭头初中开展赴市烈士陵园清明祭扫活动
2023-03-29 -
世界最新:七水烘干硫酸亚铁商品报价动态(2023-03-29)
2023-03-29 -
晒被子晒多长时间最好?_焦点热门
2023-03-29 -
1-2月湖北全省水路货运增长18.5%
2023-03-29 -
太空里的“火眼金睛” 高光谱综合观测卫星展现重要应用成果
2023-03-29 -
荣耀大天使如何解绑手机 荣耀大天使绑定手机号方法|全球速看
2023-03-29 -
焦点滚动:西安交通大学能动学院2023年硕士研究生调剂系统报名时间已公布
2023-03-29 -
比亚迪净利首破百亿,冲击400万辆销量成2023年关键一役
2023-03-29 -
韩国抗议日本教科书“歪曲历史” 促日方“拿出诚意”|当前热文
2023-03-29 -
甘肃黄羊抽水蓄能电站开工
2023-03-29 -
新双少合砍54分广厦复仇辽宁。辽篮恢复主客场以来客场仅胜宁波!
2023-03-29
-
守住网络直播的伦理底线
2021-12-16 -
石窟寺文化需要基于保护的“新开发”
2021-12-16 -
电影工作者不能远离生活
2021-12-16 -
提升隧道安全管控能力 智慧高速让司乘安心
2021-12-16 -
人民财评:提升消费体验,服务同样重要
2021-12-16 -
卫冕?突破?旗手?——武大靖留给北京冬奥会三大悬念
2021-12-16 -
新能源车险专属条款出台“三电”系统、起火燃烧等都可保
2021-12-16 -
美术作品中的党史 | 第97集《窗外》
2021-12-16 -
基金销售业务违规!浦发银行厦门分行等被厦门证监局责令改正
2021-12-16 -
保持稳定发展有支撑——从11月“成绩单”看中国经济走势
2021-12-16