prometheus监控应用数据(一)
以下代码实现均使用go
语言,至于其他语言请参照其他语言的prometheus api
文档
- 获取
go package: prometheus
:go get -u github.com/prometheus/client_golang/prometheus
- 搭建程序基本骨架
- IP地址暂定为:
localhost
- 启用prometheus的监控端口是2112
- 以
/metrics
路由进行访问,所以获取监控数据的完整访问路径为:localhost:2122/metrics
执行结果如下:package test import ( "github.com/prometheus/client_golang/prometheus/promhttp" "net/http" "testing" ) func TestPrometheus(t *testing.T) { http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":2112", nil) }
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 0 go_gc_duration_seconds{quantile="0.25"} 0 go_gc_duration_seconds{quantile="0.5"} 0 go_gc_duration_seconds{quantile="0.75"} 0 go_gc_duration_seconds{quantile="1"} 0 go_gc_duration_seconds_sum 0 go_gc_duration_seconds_count 0 # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge go_goroutines 8 # HELP go_info Information about the Go environment. # TYPE go_info gauge go_info{version="go1.19.2"} 1 # HELP go_memstats_alloc_bytes Number of bytes allocated and still in use. # TYPE go_memstats_alloc_bytes gauge go_memstats_alloc_bytes 1.622128e+06 # HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed. # TYPE go_memstats_alloc_bytes_total counter go_memstats_alloc_bytes_total 1.622128e+06 # HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table. # TYPE go_memstats_buck_hash_sys_bytes gauge go_memstats_buck_hash_sys_bytes 1.449315e+06 # HELP go_memstats_frees_total Total number of frees. # TYPE go_memstats_frees_total counter go_memstats_frees_total 1955 # HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata. # TYPE go_memstats_gc_sys_bytes gauge go_memstats_gc_sys_bytes 5.975528e+06 # HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use. # TYPE go_memstats_heap_alloc_bytes gauge go_memstats_heap_alloc_bytes 1.622128e+06 # HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used. # TYPE go_memstats_heap_idle_bytes gauge go_memstats_heap_idle_bytes 4.530176e+06 # HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use. # TYPE go_memstats_heap_inuse_bytes gauge go_memstats_heap_inuse_bytes 3.629056e+06 # HELP go_memstats_heap_objects Number of allocated objects. # TYPE go_memstats_heap_objects gauge go_memstats_heap_objects 4503 # HELP go_memstats_heap_released_bytes Number of heap bytes released to OS. # TYPE go_memstats_heap_released_bytes gauge go_memstats_heap_released_bytes 4.530176e+06 # HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system. # TYPE go_memstats_heap_sys_bytes gauge go_memstats_heap_sys_bytes 8.159232e+06 # HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection. # TYPE go_memstats_last_gc_time_seconds gauge go_memstats_last_gc_time_seconds 0 # HELP go_memstats_lookups_total Total number of pointer lookups. # TYPE go_memstats_lookups_total counter go_memstats_lookups_total 0 # HELP go_memstats_mallocs_total Total number of mallocs. # TYPE go_memstats_mallocs_total counter go_memstats_mallocs_total 6458 # HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures. # TYPE go_memstats_mcache_inuse_bytes gauge go_memstats_mcache_inuse_bytes 4672 # HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system. # TYPE go_memstats_mcache_sys_bytes gauge go_memstats_mcache_sys_bytes 16352 # HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures. # TYPE go_memstats_mspan_inuse_bytes gauge go_memstats_mspan_inuse_bytes 46648 # HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system. # TYPE go_memstats_mspan_sys_bytes gauge go_memstats_mspan_sys_bytes 48960 # HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place. # TYPE go_memstats_next_gc_bytes gauge go_memstats_next_gc_bytes 4.194304e+06 # HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations. # TYPE go_memstats_other_sys_bytes gauge go_memstats_other_sys_bytes 1.081389e+06 # HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator. # TYPE go_memstats_stack_inuse_bytes gauge go_memstats_stack_inuse_bytes 229376 # HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator. # TYPE go_memstats_stack_sys_bytes gauge go_memstats_stack_sys_bytes 229376 # HELP go_memstats_sys_bytes Number of bytes obtained from system. # TYPE go_memstats_sys_bytes gauge go_memstats_sys_bytes 1.6960152e+07 # HELP go_threads Number of OS threads created. # TYPE go_threads gauge go_threads 6 # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. # TYPE process_cpu_seconds_total counter process_cpu_seconds_total 0.046875 # HELP process_max_fds Maximum number of open file descriptors. # TYPE process_max_fds gauge process_max_fds 1.6777216e+07 # HELP process_open_fds Number of open file descriptors. # TYPE process_open_fds gauge process_open_fds 105 # HELP process_resident_memory_bytes Resident memory size in bytes. # TYPE process_resident_memory_bytes gauge process_resident_memory_bytes 1.3832192e+07 # HELP process_start_time_seconds Start time of the process since unix epoch in seconds. # TYPE process_start_time_seconds gauge process_start_time_seconds 1.686533234e+09 # HELP process_virtual_memory_bytes Virtual memory size in bytes. # TYPE process_virtual_memory_bytes gauge process_virtual_memory_bytes 2.3031808e+07 # HELP promhttp_metric_handler_requests_in_flight Current number of scrapes being served. # TYPE promhttp_metric_handler_requests_in_flight gauge promhttp_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 counter promhttp_metric_handler_requests_total{code="200"} 0 promhttp_metric_handler_requests_total{code="500"} 0 promhttp_metric_handler_requests_total{code="503"} 0
- IP地址暂定为:
- 监控程序自定义数据
以下定义要进行监控的业务数据- 当前进入课堂的学生数量
- 当前进入课堂的学生的详细信息:ID和Name
var ( // 当前在课堂中的学生数量 studentNumber = promauto.NewCounter(prometheus.CounterOpts{ Name: "StudentNumber", Help: "The number of students who has entered into the class room", }) // 当前在课堂中的学生详情:ID+Name studentDetails = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Name: "EveryStudentDetail", Help: "Every student detail", }, []string{"id", "name"}) )
- 注册业务数据到prometheus框架
prometheus.MustRegister(studentDetails)
-
实现以下业务逻辑
- 每隔5秒一个学生进入课堂,并将学生数统计到
studentNumber
中
id := 0 name := "student-" for { room.AddStudent(strconv.Itoa(id), name+strconv.Itoa(id)) studentNumber.Inc() time.Sleep(time.Second * 5) id++ }
- 每隔2s将课堂中的学生统计到我们第3步中定义的监控变量
studentDetails
中
ticker := time.NewTicker(time.Second * 2) for { select { case <-ticker.C: RefreshStuDetails() } } func RefreshStuDetails() { gClassRoom.mu.Lock() defer gClassRoom.mu.Unlock() studentDetails.Reset() for _, student := range gClassRoom.students { studentDetails.WithLabelValues(student.ID, student.Name) } }
- 每隔5秒一个学生进入课堂,并将学生数统计到
-
运行函数
TestPrometheus
,程序完整代码详见第8步 -
打开浏览器,访问地址
localhost:2122/metrics
,即可看到形如第2步中的输出内容,与之不同的是,内容中新增了StudentNumber
,EveryStudentDetail
相关内容的条项,条项下分别输出了当前课堂的学生数量,当前课堂学生的详细信息。如下图所示:
-
程序完整代码如下:
package test
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
"log"
"net/http"
"strconv"
"sync"
"testing"
"time"
)
type Student struct {
ID string
Name string
}
// 以下定义课堂和学生相关的数据结构,出于封装考虑,可以放到另外一个文件中, 这里为了演示
// 先放到一个文件中
type ClassRoom struct {
mu sync.RWMutex
students map[string]*Student
}
func NewClassRoom() *ClassRoom {
return &ClassRoom{
students: make(map[string]*Student),
}
}
func (r *ClassRoom) AddStudent(id string, name string) {
r.mu.Lock()
defer r.mu.Unlock()
r.students[id] = &Student{
ID: id,
Name: name,
}
}
// 课堂、学生相关数据结构定义结束
var gClassRoom *ClassRoom
// 定义需要监控的数据结构
var (
// 当前在课堂中的学生数量
studentNumber = promauto.NewCounter(prometheus.CounterOpts{
Name: "StudentNumber",
Help: "The number of students who has entered into the class room",
})
// 当前在课堂中的学生详情:ID+Name
studentDetails = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "EveryStudentDetail",
Help: "Every student detail",
}, []string{"id", "name"})
)
// StudentEnterClassRoom Simulate the scene where students enter the classroom every 5 seconds
func StudentEnterClassRoom(r *ClassRoom) {
go func(room *ClassRoom) {
defer func() {
if p := recover(); p != nil {
log.Panicf("%v", p)
}
}()
id := 0
name := "student-"
for {
room.AddStudent(strconv.Itoa(id), name+strconv.Itoa(id))
studentNumber.Inc()
time.Sleep(time.Second * 5)
id++
}
}(r)
}
func TestPrometheus(t *testing.T) {
gClassRoom = NewClassRoom()
StudentEnterClassRoom(gClassRoom) // 每过5s一个学生进入课堂
// 将需要的监控数据注册到prometheus
prometheus.MustRegister(studentDetails)
// 每2s刷新一下监控数据
go func() {
defer func() {
if p := recover(); p != nil {
log.Panicf("%v", p)
}
}()
ticker := time.NewTicker(time.Second * 2)
for {
select {
case <-ticker.C:
RefreshStuDetails()
}
}
}()
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":2112", nil)
}
func RefreshStuDetails() {
gClassRoom.mu.Lock()
defer gClassRoom.mu.Unlock()
studentDetails.Reset()
for _, student := range gClassRoom.students {
studentDetails.WithLabelValues(student.ID, student.Name)
}
}