-
Notifications
You must be signed in to change notification settings - Fork 83
/
http_request.go
127 lines (112 loc) · 3.22 KB
/
http_request.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
// Copyright 2022 The kubegems.io Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package exporter
import (
"sync"
"time"
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus"
"kubegems.io/kubegems/pkg/log"
)
type basicInfo struct {
requestTotalCount int64
requestTotalSeconds float64
start time.Time
countBuckets map[float64]uint64
}
type RequestCollector struct {
basicInfo
requestCount *prometheus.Desc
upDuration *prometheus.Desc
requestTime *prometheus.Desc
mutex sync.Mutex
}
func GetRequestCollector() *RequestCollector {
tmp := GetInitiatedCollectors()
return tmp["request"].(*RequestCollector)
}
func NewRequestCollector() Collectorfunc {
return func(logger *log.Logger) (Collector, error) {
return &RequestCollector{
requestCount: prometheus.NewDesc(
prometheus.BuildFQName(getNamespace(), "http", "requests_total"),
"Gems server request total",
nil,
nil,
),
upDuration: prometheus.NewDesc(
prometheus.BuildFQName(getNamespace(), "up", "duration_seconds"),
"Gems server up duration",
nil,
nil,
),
requestTime: prometheus.NewDesc(
prometheus.BuildFQName(getNamespace(), "http", "request_duration_seconds"),
"Gems server request duration seconds",
nil,
nil,
),
basicInfo: basicInfo{
start: time.Now(),
countBuckets: map[float64]uint64{
0.005: 0,
0.01: 0,
0.025: 0,
0.05: 0,
0.1: 0,
0.25: 0,
0.5: 0,
1: 0,
2.5: 0,
5: 0,
10: 0,
},
},
mutex: sync.Mutex{},
}, nil
}
}
func (rc *RequestCollector) HandlerFunc() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
dur := time.Since(start).Seconds()
rc.mutex.Lock()
defer rc.mutex.Unlock()
for k := range rc.countBuckets {
if dur < k {
rc.countBuckets[k] = rc.countBuckets[k] + 1
}
}
rc.basicInfo.requestTotalCount++
rc.basicInfo.requestTotalSeconds += dur
}
}
// Update implements Collector
func (rc *RequestCollector) Update(ch chan<- prometheus.Metric) error {
rc.mutex.Lock()
defer rc.mutex.Unlock()
ch <- prometheus.MustNewConstMetric(rc.requestCount, prometheus.CounterValue, float64(rc.basicInfo.requestTotalCount))
ch <- prometheus.MustNewConstMetric(rc.upDuration, prometheus.CounterValue, float64(time.Since(rc.start).Seconds()))
ch <- prometheus.MustNewConstHistogram(rc.requestTime, uint64(rc.requestTotalCount), rc.requestTotalSeconds, copyBuckets(rc.countBuckets))
return nil
}
// 复制一份 buckets map传入 Update,避免scrape时map同时读写panic
func copyBuckets(buckets map[float64]uint64) map[float64]uint64 {
ret := map[float64]uint64{}
for k, v := range buckets {
ret[k] = v
}
return ret
}