Name log fields, metrics and the Core Rule Set package for what they are (closes #192)
check / check (push) Failing after 5m32s
check / check (push) Failing after 5m32s
Log field, metric, action and event names now say what they count and, for timings, the unit. Package internal/waf is internal/coreruleset. Model: opus-5-5
This commit is contained in:
1 parent
aede434f6a
commit
9e6abf8496
58 files changed
+743
-691
No files matched your search
+12
-10
@@ -44,10 +44,10 @@ const (
|
||||
// EventAnomaly is a count of requests or bytes over an anomaly
|
||||
// threshold.
|
||||
EventAnomaly = "anomaly"
|
||||
// EventWAFBlock is a request the Core Rule Set scored at or over
|
||||
// EventCoreRuleSetMatch is a request the Core Rule Set scored at or over
|
||||
// SWW_WAF_ANOMALY_THRESHOLD, refused in block mode, let through in
|
||||
// detect mode.
|
||||
EventWAFBlock = "waf_block"
|
||||
EventCoreRuleSetMatch = "core_rule_set_match"
|
||||
// EventReputationHit is a request whose client a blocklist, the
|
||||
// CrowdSec decision list or a DNSBL zone lists, or whose AbuseIPDB score
|
||||
// is a hit.
|
||||
@@ -72,7 +72,7 @@ const (
|
||||
// default.
|
||||
func Events() []string {
|
||||
return []string{
|
||||
EventBan, EventPermanentBan, EventWAFBlock, EventAnomaly,
|
||||
EventBan, EventPermanentBan, EventCoreRuleSetMatch, EventAnomaly,
|
||||
EventReputationHit, EventSourceFailure, EventFileError,
|
||||
}
|
||||
}
|
||||
@@ -220,7 +220,7 @@ type State struct {
|
||||
// requests to it failed, and how many alerts were dropped from its full
|
||||
// queue or given up as it refused them.
|
||||
type Counts struct {
|
||||
Sent, Failed, Dropped int64
|
||||
Sent, SendFailures, Dropped int64
|
||||
}
|
||||
|
||||
// Queue takes the alerts raised, holds back those it must, and sends the
|
||||
@@ -264,7 +264,7 @@ type destination struct {
|
||||
// waiting are the alerts waiting to be sent, oldest first.
|
||||
waiting []*Alert
|
||||
|
||||
sent, failed, dropped atomic.Int64
|
||||
sent, sendFailures, dropped atomic.Int64
|
||||
}
|
||||
|
||||
// cooldownKey is what makes an alert a repeat of another: the same event
|
||||
@@ -426,7 +426,9 @@ func (q *Queue) Counts(name string) Counts {
|
||||
for _, d := range q.destinations {
|
||||
if d.name == name {
|
||||
return Counts{
|
||||
Sent: d.sent.Load(), Failed: d.failed.Load(), Dropped: d.dropped.Load(),
|
||||
Sent: d.sent.Load(),
|
||||
SendFailures: d.sendFailures.Load(),
|
||||
Dropped: d.dropped.Load(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -675,7 +677,7 @@ func (d *destination) run(ctx context.Context) {
|
||||
retryAt = time.Time{}
|
||||
case errors.Is(err, errRefused):
|
||||
d.remove(alert)
|
||||
d.failed.Add(1)
|
||||
d.sendFailures.Add(1)
|
||||
d.dropped.Add(1)
|
||||
|
||||
retryDelay = 0
|
||||
@@ -684,7 +686,7 @@ func (d *destination) run(ctx context.Context) {
|
||||
d.processLog.Warn("gave up an alert "+d.setting+" refused",
|
||||
"event", alert.Event, "error", err.Error())
|
||||
case ctx.Err() == nil: // not cut off as sww stops
|
||||
d.failed.Add(1)
|
||||
d.sendFailures.Add(1)
|
||||
|
||||
retryDelay = min(max(retryDelayFactor*retryDelay, firstRetryDelay),
|
||||
maxRetryDelay)
|
||||
@@ -871,7 +873,7 @@ func ntfyPriority(event string) string {
|
||||
return "high"
|
||||
case EventReputationHit:
|
||||
return "low"
|
||||
default: // ban, waf_block and summary
|
||||
default: // ban, core_rule_set_match and summary
|
||||
return "default"
|
||||
}
|
||||
}
|
||||
@@ -882,7 +884,7 @@ func ntfyTag(event string) string {
|
||||
switch event {
|
||||
case EventBan, EventPermanentBan:
|
||||
return "no_entry"
|
||||
case EventWAFBlock:
|
||||
case EventCoreRuleSetMatch:
|
||||
return "shield"
|
||||
case EventAnomaly:
|
||||
return "chart_with_upwards_trend"
|
||||
|
||||
@@ -897,7 +897,7 @@ func TestDestinationThatDoesNotAnswerHoldsUpNeitherOther(t *testing.T) {
|
||||
synctest.Wait()
|
||||
|
||||
wantDestinationCounts(t, q, alerts.DestinationSlack,
|
||||
alerts.Counts{Sent: 3, Failed: 1})
|
||||
alerts.Counts{Sent: 3, SendFailures: 1})
|
||||
|
||||
logged := log.String()
|
||||
if !strings.Contains(logged,
|
||||
@@ -934,7 +934,7 @@ func TestDropsAreCountedForEachDestination(t *testing.T) {
|
||||
for destination, want := range map[string]alerts.Counts{
|
||||
alerts.DestinationWebhook: {Sent: all},
|
||||
alerts.DestinationSlack: {Dropped: 1},
|
||||
alerts.DestinationNtfy: {Failed: all, Dropped: all},
|
||||
alerts.DestinationNtfy: {SendFailures: all, Dropped: all},
|
||||
} {
|
||||
wantDestinationCounts(t, q, destination, want)
|
||||
}
|
||||
@@ -1223,12 +1223,12 @@ func wantEvents(t *testing.T, webhook *standIn, want ...string) {
|
||||
// requests to it that it counts as failed, the alerts it counts as held
|
||||
// back, and those it counts as dropped for the webhook.
|
||||
func wantCounts(
|
||||
t *testing.T, q *alerts.Queue, sent, failed, suppressed, dropped int64,
|
||||
t *testing.T, q *alerts.Queue, sent, sendFailures, suppressed, dropped int64,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
wantDestinationCounts(t, q, alerts.DestinationWebhook,
|
||||
alerts.Counts{Sent: sent, Failed: failed, Dropped: dropped})
|
||||
alerts.Counts{Sent: sent, SendFailures: sendFailures, Dropped: dropped})
|
||||
|
||||
if q.Suppressed() != suppressed {
|
||||
t.Errorf("%d alerts held back, want %d", q.Suppressed(), suppressed)
|
||||
@@ -1281,12 +1281,12 @@ func anAlertForEachEvent() []eventMessage {
|
||||
},
|
||||
{
|
||||
alerts.Alert{
|
||||
Event: alerts.EventWAFBlock, Client: netip.MustParseAddr("192.0.2.1"),
|
||||
Event: alerts.EventCoreRuleSetMatch, Client: netip.MustParseAddr("192.0.2.1"),
|
||||
Netblock: netip.MustParsePrefix("192.0.2.1/32"),
|
||||
Reason: "refused by the Core Rule Set",
|
||||
Host: "app.example",
|
||||
},
|
||||
"fsn1app1/blog: waf_block", "default shield",
|
||||
"fsn1app1/blog: core_rule_set_match", "default shield",
|
||||
"refused by the Core Rule Set\nhost: app.example\nclient: 192.0.2.1\n" +
|
||||
"netblock: 192.0.2.1/32",
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user