mirror of
https://github.com/adnanh/webhook.git
synced 2025-08-03 16:30:29 +00:00
Add basic prometheus metrics
This commit is contained in:
parent
8d06835a8d
commit
6375264c26
1 changed files with 47 additions and 1 deletions
46
webhook.go
46
webhook.go
|
@ -21,11 +21,16 @@ import (
|
||||||
|
|
||||||
chimiddleware "github.com/go-chi/chi/middleware"
|
chimiddleware "github.com/go-chi/chi/middleware"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
|
||||||
fsnotify "gopkg.in/fsnotify.v1"
|
fsnotify "gopkg.in/fsnotify.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "2.8.0"
|
version = "2.8.0"
|
||||||
|
metricsNamespace = "webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -52,6 +57,7 @@ var (
|
||||||
setUID = flag.Int("setuid", 0, "set user ID after opening listening port; must be used with setgid")
|
setUID = flag.Int("setuid", 0, "set user ID after opening listening port; must be used with setgid")
|
||||||
httpMethods = flag.String("http-methods", "", `set default allowed HTTP methods (ie. "POST"); separate methods with comma`)
|
httpMethods = flag.String("http-methods", "", `set default allowed HTTP methods (ie. "POST"); separate methods with comma`)
|
||||||
pidPath = flag.String("pidfile", "", "create PID file at the given path")
|
pidPath = flag.String("pidfile", "", "create PID file at the given path")
|
||||||
|
metrics = flag.Bool("metrics", false, "enable prometheus metrics at /metrics")
|
||||||
|
|
||||||
responseHeaders hook.ResponseHeaders
|
responseHeaders hook.ResponseHeaders
|
||||||
hooksFiles hook.HooksFiles
|
hooksFiles hook.HooksFiles
|
||||||
|
@ -63,6 +69,31 @@ var (
|
||||||
pidFile *pidfile.PIDFile
|
pidFile *pidfile.PIDFile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// prometheus metrics
|
||||||
|
var hookCounter = promauto.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: metricsNamespace,
|
||||||
|
Name: "hook_requests_total",
|
||||||
|
Help: "Total number of hook requests",
|
||||||
|
}, []string{"hook"},
|
||||||
|
)
|
||||||
|
|
||||||
|
var hookErrorCounter = promauto.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: metricsNamespace,
|
||||||
|
Name: "hook_errors_total",
|
||||||
|
Help: "Total number of hook errors",
|
||||||
|
}, []string{"hook", "error"},
|
||||||
|
)
|
||||||
|
|
||||||
|
var hookSuccessCounter = promauto.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: metricsNamespace,
|
||||||
|
Name: "hook_success_total",
|
||||||
|
Help: "Total number of successful hook executions",
|
||||||
|
}, []string{"hook"},
|
||||||
|
)
|
||||||
|
|
||||||
func matchLoadedHook(id string) *hook.Hook {
|
func matchLoadedHook(id string) *hook.Hook {
|
||||||
for _, hooks := range loadedHooksFromFiles {
|
for _, hooks := range loadedHooksFromFiles {
|
||||||
if hook := hooks.Match(id); hook != nil {
|
if hook := hooks.Match(id); hook != nil {
|
||||||
|
@ -270,6 +301,11 @@ func main() {
|
||||||
|
|
||||||
r.HandleFunc(hooksURL, hookHandler)
|
r.HandleFunc(hooksURL, hookHandler)
|
||||||
|
|
||||||
|
if *metrics {
|
||||||
|
// add /metrics handler
|
||||||
|
r.Handle("/metrics", promhttp.Handler())
|
||||||
|
}
|
||||||
|
|
||||||
// Create common HTTP server settings
|
// Create common HTTP server settings
|
||||||
svr := &http.Server{
|
svr := &http.Server{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
|
@ -315,6 +351,8 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hookCounter.With(prometheus.Labels{"hook": matchedHook.ID}).Inc()
|
||||||
|
|
||||||
// Check for allowed methods
|
// Check for allowed methods
|
||||||
var allowedMethod bool
|
var allowedMethod bool
|
||||||
|
|
||||||
|
@ -340,6 +378,8 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !allowedMethod {
|
if !allowedMethod {
|
||||||
|
hookErrorCounter.With(prometheus.Labels{"hook": matchedHook.ID, "error": "invalid_method"}).Inc()
|
||||||
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
log.Printf("[%s] HTTP %s method not allowed for hook %q", req.ID, r.Method, id)
|
log.Printf("[%s] HTTP %s method not allowed for hook %q", req.ID, r.Method, id)
|
||||||
|
|
||||||
|
@ -540,6 +580,8 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
writeHttpResponseCode(w, req.ID, matchedHook.ID, matchedHook.TriggerRuleMismatchHttpResponseCode)
|
writeHttpResponseCode(w, req.ID, matchedHook.ID, matchedHook.TriggerRuleMismatchHttpResponseCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hookErrorCounter.With(prometheus.Labels{"hook": matchedHook.ID, "error": "rules"}).Inc()
|
||||||
|
|
||||||
// if none of the hooks got triggered
|
// if none of the hooks got triggered
|
||||||
log.Printf("[%s] %s got matched, but didn't get triggered because the trigger rules were not satisfied\n", req.ID, matchedHook.ID)
|
log.Printf("[%s] %s got matched, but didn't get triggered because the trigger rules were not satisfied\n", req.ID, matchedHook.ID)
|
||||||
|
|
||||||
|
@ -559,6 +601,7 @@ func handleHook(h *hook.Hook, r *hook.Request) (string, error) {
|
||||||
|
|
||||||
cmdPath, err := exec.LookPath(lookpath)
|
cmdPath, err := exec.LookPath(lookpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
hookErrorCounter.With(prometheus.Labels{"hook": h.ID, "error": "command"}).Inc()
|
||||||
log.Printf("[%s] error in %s", r.ID, err)
|
log.Printf("[%s] error in %s", r.ID, err)
|
||||||
|
|
||||||
// check if parameters specified in execute-command by mistake
|
// check if parameters specified in execute-command by mistake
|
||||||
|
@ -620,6 +663,7 @@ func handleHook(h *hook.Hook, r *hook.Request) (string, error) {
|
||||||
log.Printf("[%s] command output: %s\n", r.ID, out)
|
log.Printf("[%s] command output: %s\n", r.ID, out)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
hookErrorCounter.With(prometheus.Labels{"hook": h.ID, "error": "command"}).Inc()
|
||||||
log.Printf("[%s] error occurred: %+v\n", r.ID, err)
|
log.Printf("[%s] error occurred: %+v\n", r.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,6 +677,8 @@ func handleHook(h *hook.Hook, r *hook.Request) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hookSuccessCounter.With(prometheus.Labels{"hook": h.ID}).Inc()
|
||||||
|
|
||||||
log.Printf("[%s] finished handling %s\n", r.ID, h.ID)
|
log.Printf("[%s] finished handling %s\n", r.ID, h.ID)
|
||||||
|
|
||||||
return string(out), err
|
return string(out), err
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue