Skip to content

Commit

Permalink
Merge pull request #1174 from nickysemenza/go-metrics-prometheus
Browse files Browse the repository at this point in the history
replace deprecated go-metrics with prometheus
  • Loading branch information
nickysemenza authored Feb 12, 2021
2 parents 6eb1640 + 84e7ff5 commit c6f04ed
Show file tree
Hide file tree
Showing 672 changed files with 237,544 additions and 16,385 deletions.
105 changes: 32 additions & 73 deletions cmd/multirootca/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (
"github.com/cloudflare/cfssl/log"
"github.com/cloudflare/cfssl/signer"
"github.com/cloudflare/cfssl/whitelist"
metrics "github.com/cloudflare/go-metrics"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

// A SignatureResponse contains only a certificate, as there is no other
Expand All @@ -25,56 +26,36 @@ type SignatureResponse struct {
type filter func(string, *signer.SignRequest) bool

var filters = map[string][]filter{}
var (
requests = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "requests_total",
Help: "How many requests for each operation type and signer were succesfully processed.",
},
[]string{"operation", "signer"},
)
erroredRequests = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "requests_errored_total",
Help: "How many requests for each operation type resulted in an error.",
},
[]string{"operation", "signer"},
)
badInputs = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "bad_inputs_total",
Help: "How many times the input was malformed or not allowed.",
},
[]string{"operation"},
)
)

type signerStats struct {
Counter metrics.Counter
Rate metrics.Meter
}

var stats struct {
Registry metrics.Registry
Requests map[string]signerStats
TotalRequestRate metrics.Meter
ErrorPercent metrics.GaugeFloat64
ErrorRate metrics.Meter
}

func initStats() {
stats.Registry = metrics.NewRegistry()

stats.Requests = map[string]signerStats{}

// signers is defined in ca.go
for k := range signers {
stats.Requests[k] = signerStats{
Counter: metrics.NewRegisteredCounter("requests:"+k, stats.Registry),
Rate: metrics.NewRegisteredMeter("request-rate:"+k, stats.Registry),
}
}

stats.TotalRequestRate = metrics.NewRegisteredMeter("total-request-rate", stats.Registry)
stats.ErrorPercent = metrics.NewRegisteredGaugeFloat64("error-percent", stats.Registry)
stats.ErrorRate = metrics.NewRegisteredMeter("error-rate", stats.Registry)
}

// incError increments the error count and updates the error percentage.
func incErrors() {
stats.ErrorRate.Mark(1)
eCtr := float64(stats.ErrorRate.Count())
rCtr := float64(stats.TotalRequestRate.Count())
stats.ErrorPercent.Update(eCtr / rCtr * 100)
}

// incRequests increments the request count and updates the error percentage.
func incRequests() {
stats.TotalRequestRate.Mark(1)
eCtr := float64(stats.ErrorRate.Count())
rCtr := float64(stats.TotalRequestRate.Count())
stats.ErrorPercent.Update(eCtr / rCtr * 100)
}
const (
signOperation = "sign"
)

func fail(w http.ResponseWriter, req *http.Request, status, code int, msg, ad string) {
incErrors()
badInputs.WithLabelValues(signOperation).Inc()

if ad != "" {
ad = " (" + ad + ")"
Expand All @@ -95,8 +76,6 @@ func fail(w http.ResponseWriter, req *http.Request, status, code int, msg, ad st
}

func dispatchRequest(w http.ResponseWriter, req *http.Request) {
incRequests()

if req.Method != "POST" {
fail(w, req, http.StatusMethodNotAllowed, 1, "only POST is permitted", "")
return
Expand Down Expand Up @@ -146,10 +125,7 @@ func dispatchRequest(w http.ResponseWriter, req *http.Request) {
fail(w, req, http.StatusBadRequest, 1, "bad request", "request is for non-existent label "+sigRequest.Label)
return
}

stats.Requests[sigRequest.Label].Counter.Inc(1)
stats.Requests[sigRequest.Label].Rate.Mark(1)

requests.WithLabelValues(signOperation, sigRequest.Label).Inc()
// Sanity checks to ensure that we have a valid policy. This
// should have been checked in NewAuthSignHandler.
policy := s.Policy()
Expand Down Expand Up @@ -195,12 +171,14 @@ func dispatchRequest(w http.ResponseWriter, req *http.Request) {

cert, err := s.Sign(sigRequest)
if err != nil {
erroredRequests.WithLabelValues(signOperation, sigRequest.Label).Inc()
fail(w, req, http.StatusBadRequest, 1, "bad request", "signature failed: "+err.Error())
return
}

x509Cert, err := helpers.ParseCertificatePEM(cert)
if err != nil {
erroredRequests.WithLabelValues(signOperation, sigRequest.Label).Inc()
fail(w, req, http.StatusInternalServerError, 1, "bad certificate", err.Error())
}

Expand All @@ -219,22 +197,3 @@ func metricsDisallowed(w http.ResponseWriter, req *http.Request) {
log.Warning("attempt to access metrics endpoint from external address ", req.RemoteAddr)
http.NotFound(w, req)
}

func dumpMetrics(w http.ResponseWriter, req *http.Request) {
log.Info("whitelisted requested for metrics endpoint")
var statsOut = struct {
Metrics metrics.Registry `json:"metrics"`
Signers []string `json:"signers"`
}{stats.Registry, make([]string, 0, len(signers))}

for signer := range signers {
statsOut.Signers = append(statsOut.Signers, signer)
}

out, err := json.Marshal(statsOut)
if err != nil {
log.Errorf("failed to dump metrics: %v", err)
}

w.Write(out)
}
8 changes: 2 additions & 6 deletions cmd/multirootca/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/cloudflare/cfssl/signer"
"github.com/cloudflare/cfssl/signer/local"
"github.com/cloudflare/cfssl/whitelist"
"github.com/prometheus/client_golang/prometheus/promhttp"

_ "github.com/go-sql-driver/mysql" // import to support MySQL
_ "github.com/lib/pq" // import to support Postgres
Expand Down Expand Up @@ -76,7 +77,6 @@ func main() {
}

defaultLabel = *flagDefaultLabel
initStats()

infoHandler, err := info.NewMultiHandler(signers, defaultLabel)
if err != nil {
Expand All @@ -86,14 +86,10 @@ func main() {
var localhost = whitelist.NewBasic()
localhost.Add(net.ParseIP("127.0.0.1"))
localhost.Add(net.ParseIP("::1"))
metrics, err := whitelist.NewHandlerFunc(dumpMetrics, metricsDisallowed, localhost)
if err != nil {
log.Criticalf("failed to set up the metrics whitelist: %v", err)
}

http.HandleFunc("/api/v1/cfssl/authsign", dispatchRequest)
http.Handle("/api/v1/cfssl/info", infoHandler)
http.Handle("/api/v1/cfssl/metrics", metrics)
http.Handle("/metrics", promhttp.Handler())

if *flagEndpointCert == "" && *flagEndpointKey == "" {
log.Info("Now listening on ", *flagAddr)
Expand Down
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ require (
github.com/GeertJohan/go.rice v1.0.0
github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261 // indirect
github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a
github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41
github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c
github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7 // indirect
github.com/go-sql-driver/mysql v1.4.0
Expand All @@ -19,9 +18,8 @@ require (
github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28 // indirect
github.com/lib/pq v1.3.0
github.com/mattn/go-sqlite3 v1.10.0
github.com/pkg/errors v0.8.0 // indirect
github.com/prometheus/client_golang v1.9.0
github.com/stretchr/testify v1.4.0
github.com/weppos/publicsuffix-go v0.13.0 // indirect
github.com/ziutek/mymysql v1.5.4 // indirect
github.com/zmap/zcrypto v0.0.0-20201128221613-3719af1573cf
github.com/zmap/zlint/v3 v3.0.0
Expand Down
Loading

0 comments on commit c6f04ed

Please sign in to comment.