-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcollector_httpserver.go
129 lines (111 loc) · 3.63 KB
/
collector_httpserver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package xmonitor
import (
"strconv"
"sync"
"time"
"github.com/prometheus/client_golang/prometheus"
)
type HttpServerCollector interface {
MonitorRequest(method, path string, reqSize int) func(statusCode, respSize int)
MonitorLogic(uri string) func(status string)
}
func NewHttpServerCollector(opts ...CollectorConfOption) HttpServerCollector {
conf := NewCollectorConf(opts...)
if conf.MonitorRegister == nil {
panic("must set MonitorRegister")
}
initMetrics(conf)
return &httpCollector{
conf: conf,
}
}
const (
tagMethod = "method"
tagPath = "path"
tagStatus = "http_status"
tagUri = "uri"
tagLogicStatus = "status"
)
var (
// 进程内必须唯一,所以放到全局没有放到 httpCollector 内
latencyHistogram *prometheus.HistogramVec
inFlowCounter *prometheus.CounterVec
outFlowCounter *prometheus.CounterVec
requestCounter *prometheus.CounterVec
logicLatency *prometheus.HistogramVec
logicCounter *prometheus.CounterVec
initOnce sync.Once
)
func initMetrics(cc *CollectorConf) {
initOnce.Do(func() {
latencyHistogram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_server_latency",
Help: "The HTTP request latencies in seconds.",
Buckets: cc.Buckets,
ConstLabels: cc.ConstLabels,
}, []string{tagMethod, tagPath})
inFlowCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_server_request_size_bytes",
Help: "The HTTP request sizes in bytes.",
ConstLabels: cc.ConstLabels,
}, []string{tagMethod, tagPath})
outFlowCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_server_response_size_byte",
Help: "The HTTP response sizes in bytes.",
ConstLabels: cc.ConstLabels,
}, []string{tagMethod, tagPath})
requestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_server_request_count",
Help: "Total number of HTTP requests made.",
ConstLabels: cc.ConstLabels,
}, []string{tagMethod, tagPath, tagStatus})
logicLatency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "server_logic_latency",
Help: "The server logic latencies in seconds.",
Buckets: cc.Buckets,
ConstLabels: cc.ConstLabels,
}, []string{tagUri})
logicCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "server_logic_count",
Help: "Total number of logic made.",
ConstLabels: cc.ConstLabels,
}, []string{tagUri, tagLogicStatus})
cc.MonitorRegister(latencyHistogram)
cc.MonitorRegister(inFlowCounter)
cc.MonitorRegister(outFlowCounter)
cc.MonitorRegister(requestCounter)
cc.MonitorRegister(logicLatency)
cc.MonitorRegister(logicCounter)
})
}
type httpCollector struct {
conf *CollectorConf
}
func (h *httpCollector) MonitorLogic(uri string) func(string) {
start := time.Now()
return func(status string) {
logicLatency.WithLabelValues(uri).Observe(time.Since(start).Seconds())
logicCounter.WithLabelValues(uri, status).Inc()
}
}
func (h *httpCollector) MonitorRequest(method, path string, reqSize int) func(statusCode, respSize int) {
if reqSize > 0 {
inFlowCounter.WithLabelValues(method, path).Add(float64(reqSize))
}
start := time.Now()
return func(statusCode, respSize int) {
if h.conf.IgnoreLatency != nil && !h.conf.IgnoreLatency(statusCode) {
latencyHistogram.WithLabelValues(method, path).Observe(time.Since(start).Seconds())
}
requestCounter.WithLabelValues(method, path, strconv.Itoa(statusCode)).Inc()
if respSize > 0 {
outFlowCounter.WithLabelValues(method, path).Add(float64(respSize))
}
}
}