@@ -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
-
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4