metrics: Add rule action metrics
This commit is contained in:
@@ -43,7 +43,8 @@ func init() {
|
|||||||
return nil, fmt.Errorf("no registered challenges found in rule %s", ruleName)
|
return nil, fmt.Errorf("no registered challenges found in rule %s", ruleName)
|
||||||
}
|
}
|
||||||
|
|
||||||
passHandler, ok := Register[policy.RuleAction(strings.ToUpper(params.PassAction))]
|
passAction := policy.RuleAction(strings.ToUpper(params.PassAction))
|
||||||
|
passHandler, ok := Register[passAction]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unknown pass action %s", params.PassAction)
|
return nil, fmt.Errorf("unknown pass action %s", params.PassAction)
|
||||||
}
|
}
|
||||||
@@ -53,7 +54,8 @@ func init() {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
failHandler, ok := Register[policy.RuleAction(strings.ToUpper(params.FailAction))]
|
failAction := policy.RuleAction(strings.ToUpper(params.FailAction))
|
||||||
|
failHandler, ok := Register[failAction]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unknown pass action %s", params.FailAction)
|
return nil, fmt.Errorf("unknown pass action %s", params.FailAction)
|
||||||
}
|
}
|
||||||
@@ -69,8 +71,10 @@ func init() {
|
|||||||
Continue: cont,
|
Continue: cont,
|
||||||
Challenges: regs,
|
Challenges: regs,
|
||||||
|
|
||||||
PassAction: passActionHandler,
|
PassAction: passAction,
|
||||||
FailAction: failActionHandler,
|
PassActionHandler: passActionHandler,
|
||||||
|
FailAction: failAction,
|
||||||
|
FailActionHandler: failActionHandler,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
Register[policy.RuleActionCHALLENGE] = func(state challenge.StateInterface, ruleName, ruleHash string, settings ast.Node) (Handler, error) {
|
Register[policy.RuleActionCHALLENGE] = func(state challenge.StateInterface, ruleName, ruleHash string, settings ast.Node) (Handler, error) {
|
||||||
@@ -104,8 +108,10 @@ type Challenge struct {
|
|||||||
Continue bool
|
Continue bool
|
||||||
Challenges []*challenge.Registration
|
Challenges []*challenge.Registration
|
||||||
|
|
||||||
PassAction Handler
|
PassAction policy.RuleAction
|
||||||
FailAction Handler
|
PassActionHandler Handler
|
||||||
|
FailAction policy.RuleAction
|
||||||
|
FailActionHandler Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Challenge) Handle(logger *slog.Logger, w http.ResponseWriter, r *http.Request, done func() (backend http.Handler)) (next bool, err error) {
|
func (a Challenge) Handle(logger *slog.Logger, w http.ResponseWriter, r *http.Request, done func() (backend http.Handler)) (next bool, err error) {
|
||||||
@@ -120,7 +126,8 @@ func (a Challenge) Handle(logger *slog.Logger, w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we passed!
|
// we passed!
|
||||||
return a.PassAction.Handle(logger.With("challenge", reg.Name), w, r, done)
|
data.State.ActionHit(r, a.PassAction, logger)
|
||||||
|
return a.PassActionHandler.Handle(logger.With("challenge", reg.Name), w, r, done)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// none matched, issue challenges in sequential priority
|
// none matched, issue challenges in sequential priority
|
||||||
@@ -146,7 +153,8 @@ func (a Challenge) Handle(logger *slog.Logger, w http.ResponseWriter, r *http.Re
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.PassAction.Handle(logger.With("challenge", reg.Name), w, r, done)
|
data.State.ActionHit(r, a.PassAction, logger)
|
||||||
|
return a.PassActionHandler.Handle(logger.With("challenge", reg.Name), w, r, done)
|
||||||
case challenge.VerifyResultNotOK:
|
case challenge.VerifyResultNotOK:
|
||||||
// we have had the challenge checked, but it's not ok!
|
// we have had the challenge checked, but it's not ok!
|
||||||
// safe to continue
|
// safe to continue
|
||||||
@@ -160,7 +168,8 @@ func (a Challenge) Handle(logger *slog.Logger, w http.ResponseWriter, r *http.Re
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.FailAction.Handle(logger, w, r, done)
|
data.State.ActionHit(r, a.FailAction, logger)
|
||||||
|
return a.FailActionHandler.Handle(logger, w, r, done)
|
||||||
case challenge.VerifyResultNone:
|
case challenge.VerifyResultNone:
|
||||||
// challenge was issued
|
// challenge was issued
|
||||||
if reg.Class == challenge.ClassTransparent {
|
if reg.Class == challenge.ClassTransparent {
|
||||||
@@ -177,5 +186,6 @@ func (a Challenge) Handle(logger *slog.Logger, w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nothing matched, execute default action
|
// nothing matched, execute default action
|
||||||
return a.FailAction.Handle(logger, w, r, done)
|
data.State.ActionHit(r, a.FailAction, logger)
|
||||||
|
return a.FailActionHandler.Handle(logger, w, r, done)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ type StateInterface interface {
|
|||||||
|
|
||||||
RuleHit(r *http.Request, name string, logger *slog.Logger)
|
RuleHit(r *http.Request, name string, logger *slog.Logger)
|
||||||
RuleMiss(r *http.Request, name string, logger *slog.Logger)
|
RuleMiss(r *http.Request, name string, logger *slog.Logger)
|
||||||
|
ActionHit(r *http.Request, name policy.RuleAction, logger *slog.Logger)
|
||||||
|
|
||||||
Logger(r *http.Request) *slog.Logger
|
Logger(r *http.Request) *slog.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"git.gammaspectra.live/git/go-away/embed"
|
"git.gammaspectra.live/git/go-away/embed"
|
||||||
"git.gammaspectra.live/git/go-away/lib/action"
|
"git.gammaspectra.live/git/go-away/lib/action"
|
||||||
"git.gammaspectra.live/git/go-away/lib/challenge"
|
"git.gammaspectra.live/git/go-away/lib/challenge"
|
||||||
|
"git.gammaspectra.live/git/go-away/lib/policy"
|
||||||
"git.gammaspectra.live/git/go-away/utils"
|
"git.gammaspectra.live/git/go-away/utils"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@@ -130,6 +131,7 @@ func (state *State) handleRequest(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.RuleHit(r, "DEFAULT", lg)
|
state.RuleHit(r, "DEFAULT", lg)
|
||||||
|
data.State.ActionHit(r, policy.RuleActionPASS, lg)
|
||||||
|
|
||||||
// default pass
|
// default pass
|
||||||
_, _ = action.Pass{}.Handle(lg, w, r, func() http.Handler {
|
_, _ = action.Pass{}.Handle(lg, w, r, func() http.Handler {
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ func (state *State) RuleMiss(r *http.Request, name string, logger *slog.Logger)
|
|||||||
state.metrics.Rule(name, "miss")
|
state.metrics.Rule(name, "miss")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (state *State) ActionHit(r *http.Request, name policy.RuleAction, logger *slog.Logger) {
|
||||||
|
state.metrics.Action(name)
|
||||||
|
}
|
||||||
|
|
||||||
func (state *State) Logger(r *http.Request) *slog.Logger {
|
func (state *State) Logger(r *http.Request) *slog.Logger {
|
||||||
return GetLoggerForRequest(r)
|
return GetLoggerForRequest(r)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package lib
|
package lib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.gammaspectra.live/git/go-away/lib/policy"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stateMetrics struct {
|
type stateMetrics struct {
|
||||||
rules *prometheus.CounterVec
|
rules *prometheus.CounterVec
|
||||||
|
actions *prometheus.CounterVec
|
||||||
challenges *prometheus.CounterVec
|
challenges *prometheus.CounterVec
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,8 +18,12 @@ func newMetrics() *stateMetrics {
|
|||||||
Name: "go-away_rule_results",
|
Name: "go-away_rule_results",
|
||||||
Help: "The number of rule hits or misses",
|
Help: "The number of rule hits or misses",
|
||||||
}, []string{"rule", "result"}),
|
}, []string{"rule", "result"}),
|
||||||
|
actions: promauto.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Name: "go-away_action_results",
|
||||||
|
Help: "The number of each action issued",
|
||||||
|
}, []string{"action"}),
|
||||||
challenges: promauto.NewCounterVec(prometheus.CounterOpts{
|
challenges: promauto.NewCounterVec(prometheus.CounterOpts{
|
||||||
Name: "go-away_challenge_actions",
|
Name: "go-away_challenge_results",
|
||||||
Help: "The number of challenges issued, passed or explicitly failed",
|
Help: "The number of challenges issued, passed or explicitly failed",
|
||||||
}, []string{"challenge", "action"}),
|
}, []string{"challenge", "action"}),
|
||||||
}
|
}
|
||||||
@@ -27,6 +33,10 @@ func (metrics *stateMetrics) Rule(name, result string) {
|
|||||||
metrics.rules.With(prometheus.Labels{"rule": name, "result": result}).Inc()
|
metrics.rules.With(prometheus.Labels{"rule": name, "result": result}).Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (metrics *stateMetrics) Challenge(name, action string) {
|
func (metrics *stateMetrics) Action(action policy.RuleAction) {
|
||||||
metrics.challenges.With(prometheus.Labels{"challenge": name, "action": action}).Inc()
|
metrics.actions.With(prometheus.Labels{"action": string(action)}).Inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (metrics *stateMetrics) Challenge(name, result string) {
|
||||||
|
metrics.challenges.With(prometheus.Labels{"challenge": name, "action": result}).Inc()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ func (rule RuleState) Evaluate(logger *slog.Logger, w http.ResponseWriter, r *ht
|
|||||||
if out.Equal(types.True) == types.True {
|
if out.Equal(types.True) == types.True {
|
||||||
data.State.RuleHit(r, rule.Name, logger)
|
data.State.RuleHit(r, rule.Name, logger)
|
||||||
|
|
||||||
|
data.State.ActionHit(r, rule.Action, logger)
|
||||||
next, err = rule.Handler.Handle(lg, w, r, func() http.Handler {
|
next, err = rule.Handler.Handle(lg, w, r, func() http.Handler {
|
||||||
r.Header.Set("X-Away-Rule", rule.Name)
|
r.Header.Set("X-Away-Rule", rule.Name)
|
||||||
r.Header.Set("X-Away-Hash", rule.Hash)
|
r.Header.Set("X-Away-Hash", rule.Hash)
|
||||||
|
|||||||
Reference in New Issue
Block a user