@@ -13,7 +13,8 @@ import (
13
13
"github.com/cloudflare/cfssl/log"
14
14
"github.com/cloudflare/cfssl/signer"
15
15
"github.com/cloudflare/cfssl/whitelist"
16
- metrics "github.com/cloudflare/go-metrics"
16
+ "github.com/prometheus/client_golang/prometheus"
17
+ "github.com/prometheus/client_golang/prometheus/promauto"
17
18
)
18
19
19
20
// A SignatureResponse contains only a certificate, as there is no other
@@ -25,56 +26,36 @@ type SignatureResponse struct {
25
26
type filter func (string , * signer.SignRequest ) bool
26
27
27
28
var filters = map [string ][]filter {}
29
+ var (
30
+ requests = promauto .NewCounterVec (
31
+ prometheus.CounterOpts {
32
+ Name : "requests_total" ,
33
+ Help : "How many requests for each operation type and signer were succesfully processed." ,
34
+ },
35
+ []string {"operation" , "signer" },
36
+ )
37
+ erroredRequests = promauto .NewCounterVec (
38
+ prometheus.CounterOpts {
39
+ Name : "requests_errored_total" ,
40
+ Help : "How many requests for each operation type resulted in an error." ,
41
+ },
42
+ []string {"operation" , "signer" },
43
+ )
44
+ badInputs = promauto .NewCounterVec (
45
+ prometheus.CounterOpts {
46
+ Name : "bad_inputs_total" ,
47
+ Help : "How many times the input was malformed or not allowed." ,
48
+ },
49
+ []string {"operation" },
50
+ )
51
+ )
28
52
29
- type signerStats struct {
30
- Counter metrics.Counter
31
- Rate metrics.Meter
32
- }
33
-
34
- var stats struct {
35
- Registry metrics.Registry
36
- Requests map [string ]signerStats
37
- TotalRequestRate metrics.Meter
38
- ErrorPercent metrics.GaugeFloat64
39
- ErrorRate metrics.Meter
40
- }
41
-
42
- func initStats () {
43
- stats .Registry = metrics .NewRegistry ()
44
-
45
- stats .Requests = map [string ]signerStats {}
46
-
47
- // signers is defined in ca.go
48
- for k := range signers {
49
- stats .Requests [k ] = signerStats {
50
- Counter : metrics .NewRegisteredCounter ("requests:" + k , stats .Registry ),
51
- Rate : metrics .NewRegisteredMeter ("request-rate:" + k , stats .Registry ),
52
- }
53
- }
54
-
55
- stats .TotalRequestRate = metrics .NewRegisteredMeter ("total-request-rate" , stats .Registry )
56
- stats .ErrorPercent = metrics .NewRegisteredGaugeFloat64 ("error-percent" , stats .Registry )
57
- stats .ErrorRate = metrics .NewRegisteredMeter ("error-rate" , stats .Registry )
58
- }
59
-
60
- // incError increments the error count and updates the error percentage.
61
- func incErrors () {
62
- stats .ErrorRate .Mark (1 )
63
- eCtr := float64 (stats .ErrorRate .Count ())
64
- rCtr := float64 (stats .TotalRequestRate .Count ())
65
- stats .ErrorPercent .Update (eCtr / rCtr * 100 )
66
- }
67
-
68
- // incRequests increments the request count and updates the error percentage.
69
- func incRequests () {
70
- stats .TotalRequestRate .Mark (1 )
71
- eCtr := float64 (stats .ErrorRate .Count ())
72
- rCtr := float64 (stats .TotalRequestRate .Count ())
73
- stats .ErrorPercent .Update (eCtr / rCtr * 100 )
74
- }
53
+ const (
54
+ signOperation = "sign"
55
+ )
75
56
76
57
func fail (w http.ResponseWriter , req * http.Request , status , code int , msg , ad string ) {
77
- incErrors ()
58
+ badInputs . WithLabelValues ( signOperation ). Inc ()
78
59
79
60
if ad != "" {
80
61
ad = " (" + ad + ")"
@@ -95,8 +76,6 @@ func fail(w http.ResponseWriter, req *http.Request, status, code int, msg, ad st
95
76
}
96
77
97
78
func dispatchRequest (w http.ResponseWriter , req * http.Request ) {
98
- incRequests ()
99
-
100
79
if req .Method != "POST" {
101
80
fail (w , req , http .StatusMethodNotAllowed , 1 , "only POST is permitted" , "" )
102
81
return
@@ -146,10 +125,7 @@ func dispatchRequest(w http.ResponseWriter, req *http.Request) {
146
125
fail (w , req , http .StatusBadRequest , 1 , "bad request" , "request is for non-existent label " + sigRequest .Label )
147
126
return
148
127
}
149
-
150
- stats .Requests [sigRequest .Label ].Counter .Inc (1 )
151
- stats .Requests [sigRequest .Label ].Rate .Mark (1 )
152
-
128
+ requests .WithLabelValues (signOperation , sigRequest .Label ).Inc ()
153
129
// Sanity checks to ensure that we have a valid policy. This
154
130
// should have been checked in NewAuthSignHandler.
155
131
policy := s .Policy ()
@@ -195,12 +171,14 @@ func dispatchRequest(w http.ResponseWriter, req *http.Request) {
195
171
196
172
cert , err := s .Sign (sigRequest )
197
173
if err != nil {
174
+ erroredRequests .WithLabelValues (signOperation , sigRequest .Label ).Inc ()
198
175
fail (w , req , http .StatusBadRequest , 1 , "bad request" , "signature failed: " + err .Error ())
199
176
return
200
177
}
201
178
202
179
x509Cert , err := helpers .ParseCertificatePEM (cert )
203
180
if err != nil {
181
+ erroredRequests .WithLabelValues (signOperation , sigRequest .Label ).Inc ()
204
182
fail (w , req , http .StatusInternalServerError , 1 , "bad certificate" , err .Error ())
205
183
}
206
184
@@ -219,22 +197,3 @@ func metricsDisallowed(w http.ResponseWriter, req *http.Request) {
219
197
log .Warning ("attempt to access metrics endpoint from external address " , req .RemoteAddr )
220
198
http .NotFound (w , req )
221
199
}
222
-
223
- func dumpMetrics (w http.ResponseWriter , req * http.Request ) {
224
- log .Info ("whitelisted requested for metrics endpoint" )
225
- var statsOut = struct {
226
- Metrics metrics.Registry `json:"metrics"`
227
- Signers []string `json:"signers"`
228
- }{stats .Registry , make ([]string , 0 , len (signers ))}
229
-
230
- for signer := range signers {
231
- statsOut .Signers = append (statsOut .Signers , signer )
232
- }
233
-
234
- out , err := json .Marshal (statsOut )
235
- if err != nil {
236
- log .Errorf ("failed to dump metrics: %v" , err )
237
- }
238
-
239
- w .Write (out )
240
- }
0 commit comments