Format Go with gofmt, then golines -m 77 (closes #215)
check / check (push) Waiting to run

script/fmt now runs golines -m 77 after gofmt, repeating golines until
it changes nothing, since one pass can leave a line the next splits.
script/fmt-check fails when either would change a file.
script/bootstrap installs golines v0.13.0 with go install, pinned to
its commit, and checks the installed version with go version -m.

The tree is reformatted. The longer lines this makes are fixed by
hand: nolint directives moved onto their own line above the statement,
one string split, and 20 functions over funlen's 80 lines shortened or
split, RunWAF and limitPercentages among them.

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-11 15:14:58 +00:00
1 parent 63e58e326b
commit 7f8a59de04
118 files changed
+9447 -2670

No files matched your search

+9 -3
View File
@@ -41,9 +41,11 @@ type busiest struct {
// for the topN busiest countries.
func newCountries(topN int) *busiest {
countries := newBusiest(topN, "country", "the client's country")
countries.refused = counterVec("sww_country_list_refusals_total",
countries.refused = counterVec(
"sww_country_list_refusals_total",
"Requests SWW_EXCLUSIVELY_ALLOWED_COUNTRIES refused, by the client's country.",
[]string{"country"})
[]string{"country"},
)
return countries
}
@@ -90,7 +92,11 @@ func (b *busiest) Collect(ch chan<- prometheus.Metric) {
// vecs returns the metrics: by AS number, those of requests and bytes; by
// country, the refusals by the country list as well.
func (b *busiest) vecs() []*prometheus.CounterVec {
vecs := []*prometheus.CounterVec{b.requests, b.requestBytes, b.responseBytes}
vecs := []*prometheus.CounterVec{
b.requests,
b.requestBytes,
b.responseBytes,
}
if b.refused != nil {
vecs = append(vecs, b.refused)
}
+109 -47
View File
@@ -79,14 +79,19 @@ func New(topN int, instanceName string) *Metrics {
Name: "sww_requests_in_flight",
Help: "Requests under way.",
}),
requests: counterVec("sww_requests_total",
"Requests, by the class of their status and their action.", byStatus),
requests: counterVec(
"sww_requests_total",
"Requests, by the class of their status and their action.",
byStatus,
),
requestBytes: counterVec("sww_request_bytes_total",
"Request body bytes, by the class of the status and the action.",
byStatus),
responseBytes: counterVec("sww_response_bytes_total",
responseBytes: counterVec(
"sww_response_bytes_total",
"Response body bytes, by the class of the status and the action.",
byStatus),
byStatus,
),
requestDuration: prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "sww_request_duration_seconds",
Help: "How long requests took, from their arrival to their end.",
@@ -95,15 +100,20 @@ func New(topN int, instanceName string) *Metrics {
Name: "sww_upstream_duration_seconds",
Help: "How long requests passed to the app took, from then to their end.",
}),
rateLimitHits: counterVec("sww_rate_limit_hits_total",
rateLimitHits: counterVec(
"sww_rate_limit_hits_total",
"Requests that broke a rate limit, a byte limit or the error burst, by "+
"its window and its kind, requests, bytes or refusals.",
[]string{"window", "kind"}),
[]string{"window", "kind"},
),
offences: counterVec("sww_offences_total",
"Offences, by kind.", []string{"kind"}),
coreRuleSetMatches: counterVec("sww_core_rule_set_matches_total",
coreRuleSetMatches: counterVec(
"sww_core_rule_set_matches_total",
"Requests that matched a rule of the Core Rule Set, by SWW_WAF_MODE "+
"and the rule's id.", []string{"mode", "rule_id"}),
"and the rule's id.",
[]string{"mode", "rule_id"},
),
countries: newCountries(topN),
asns: newASNs(topN),
GeoJSRequests: prometheus.NewCounter(prometheus.CounterOpts{
@@ -114,26 +124,41 @@ func New(topN int, instanceName string) *Metrics {
Name: "sww_geojs_failures_total",
Help: "Requests to GeoJS that failed.",
}),
RequestsWithoutGeoJSAnswer: prometheus.NewCounter(prometheus.CounterOpts{
Name: "sww_requests_without_geojs_answer_total",
Help: "Requests that needed their client's answer from GeoJS and " +
"went on without it, because GeoJS had not given it in time.",
}),
RequestsWithoutGeoJSAnswer: prometheus.NewCounter(
prometheus.CounterOpts{
Name: "sww_requests_without_geojs_answer_total",
Help: "Requests that needed their client's answer from GeoJS and " +
"went on without it, because GeoJS had not given it in time.",
},
),
stateFileWrites: counterVec("sww_state_file_writes_total",
"Writes of each state or cache file.", byFile),
stateFileWriteFailures: counterVec("sww_state_file_write_failures_total",
"Writes of each state or cache file that failed.", byFile),
stateFileLastWrite: gaugeVec("sww_state_file_last_write_timestamp_seconds",
stateFileWriteFailures: counterVec(
"sww_state_file_write_failures_total",
"Writes of each state or cache file that failed.",
byFile,
),
stateFileLastWrite: gaugeVec(
"sww_state_file_last_write_timestamp_seconds",
"When each state or cache file was last written, in seconds since 1970.",
byFile),
stateFileSize: gaugeVec("sww_state_file_size_bytes",
"The size of each state or cache file, as it was last written.", byFile),
stateFileEditsTakenIn: counterVec("sww_state_file_edits_taken_in_total",
"Edits of each state or cache file taken in while running.", byFile),
stateFileEditsSetAside: counterVec("sww_state_file_edits_set_aside_total",
byFile,
),
stateFileSize: gaugeVec(
"sww_state_file_size_bytes",
"The size of each state or cache file, as it was last written.",
byFile,
),
stateFileEditsTakenIn: counterVec(
"sww_state_file_edits_taken_in_total",
"Edits of each state or cache file taken in while running.",
byFile,
),
stateFileEditsSetAside: counterVec(
"sww_state_file_edits_set_aside_total",
"Edits of each state or cache file renamed to <name>.bad because they "+
"did not parse.",
byFile),
byFile,
),
}
m.registry.MustRegister(
@@ -162,13 +187,15 @@ func (m *Metrics) AddBansAndClients(
for _, cause := range []string{
bans.CauseLimit, bans.CauseAttack, bans.CauseAdmin, bans.CauseCrowdSec,
} {
m.registry.MustRegister(prometheus.NewCounterFunc(prometheus.CounterOpts{
Name: "sww_bans_made_total",
Help: "Bans made, by cause.",
ConstLabels: prometheus.Labels{"cause": cause},
}, func() float64 {
return float64(ledger.Made(cause))
}))
m.registry.MustRegister(
prometheus.NewCounterFunc(prometheus.CounterOpts{
Name: "sww_bans_made_total",
Help: "Bans made, by cause.",
ConstLabels: prometheus.Labels{"cause": cause},
}, func() float64 {
return float64(ledger.Made(cause))
}),
)
}
m.registry.MustRegister(
@@ -202,9 +229,11 @@ func (m *Metrics) AddBansAndClients(
// ruleFiles, read as the metrics are asked for. It is called once, before
// RuleMatched.
func (m *Metrics) AddRules(ruleFiles *rules.Files) {
m.ruleMatches = counterVec("sww_rule_matches_total",
m.ruleMatches = counterVec(
"sww_rule_matches_total",
"Requests that matched a rule of the rule files, by its id and action.",
[]string{"rule_id", "action"})
[]string{"rule_id", "action"},
)
m.registry.MustRegister(m.ruleMatches,
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
@@ -247,7 +276,10 @@ func (m *Metrics) AddRemoteLog(remote *remotelog.Sender) {
// returns, and the replacements of it that could not be read, which
// readFailures returns. The lookup package's File, which has both, cannot
// be named here: that package counts GeoJS's requests in these metrics.
func (m *Metrics) AddLookupFile(lastRead func() time.Time, readFailures func() int) {
func (m *Metrics) AddLookupFile(
lastRead func() time.Time,
readFailures func() int,
) {
m.registry.MustRegister(
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "sww_lookup_database_last_read_timestamp_seconds",
@@ -276,24 +308,38 @@ const sourceLabel = "source"
// metrics are asked for, for a list, the fetches that failed and when the
// copy in use was fetched, and for a zone, the queries made and those that
// failed. It is called once, before ReputationHit.
func (m *Metrics) AddReputation(lists *reputation.Lists, dnsbl *reputation.DNSBL) {
m.reputationHits = counterVec("sww_reputation_hits_total",
func (m *Metrics) AddReputation(
lists *reputation.Lists,
dnsbl *reputation.DNSBL,
) {
m.reputationHits = counterVec(
"sww_reputation_hits_total",
"Requests whose client a blocklist, the CrowdSec decision list, a DNSBL "+
"zone or AbuseIPDB lists, by the list's URL, the zone, or abuseipdb.",
[]string{sourceLabel})
[]string{sourceLabel},
)
m.registry.MustRegister(m.reputationHits)
for _, zone := range dnsbl.Zones() {
source := prometheus.Labels{sourceLabel: config.MaskZoneKey(zone)}
m.addReputationQueries(source, func() int { return dnsbl.Queries(zone) })
m.addReputationFailures(source, func() int { return dnsbl.Failures(zone) })
m.addReputationQueries(
source,
func() int { return dnsbl.Queries(zone) },
)
m.addReputationFailures(
source,
func() int { return dnsbl.Failures(zone) },
)
}
for _, listURL := range lists.URLs() {
source := prometheus.Labels{sourceLabel: listURL}
m.addReputationFailures(source, func() int { return lists.Failures(listURL) })
m.addReputationFailures(
source,
func() int { return lists.Failures(listURL) },
)
m.registry.MustRegister(
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "sww_reputation_last_fetch_timestamp_seconds",
@@ -395,7 +441,10 @@ func (m *Metrics) RequestStarted() {
// RequestEnded counts a request that has ended without being passed to the app,
// from its log line. duration is how long the request took.
func (m *Metrics) RequestEnded(line *requestlog.Line, duration time.Duration) {
func (m *Metrics) RequestEnded(
line *requestlog.Line,
duration time.Duration,
) {
m.inFlight.Dec()
m.count(line, duration, 0)
}
@@ -487,8 +536,10 @@ func (m *Metrics) count(
) {
class := statusClass(line.Status)
m.requests.WithLabelValues(class, line.Action).Inc()
m.requestBytes.WithLabelValues(class, line.Action).Add(float64(line.RequestBytes))
m.responseBytes.WithLabelValues(class, line.Action).Add(float64(line.ResponseBytes))
m.requestBytes.WithLabelValues(class, line.Action).
Add(float64(line.RequestBytes))
m.responseBytes.WithLabelValues(class, line.Action).
Add(float64(line.ResponseBytes))
m.requestDuration.Observe(duration.Seconds())
if upstreamDuration > 0 {
@@ -506,7 +557,10 @@ func (m *Metrics) count(
// addReputationQueries adds the counter of the queries to source, a DNSBL
// zone, or of the checks of clients with AbuseIPDB, which count tells.
func (m *Metrics) addReputationQueries(source prometheus.Labels, count func() int) {
func (m *Metrics) addReputationQueries(
source prometheus.Labels,
count func() int,
) {
m.registry.MustRegister(prometheus.NewCounterFunc(prometheus.CounterOpts{
Name: "sww_reputation_queries_total",
Help: "Queries to the DNSBL zone, or checks of clients with AbuseIPDB.",
@@ -519,7 +573,10 @@ func (m *Metrics) addReputationQueries(source prometheus.Labels, count func() in
// addReputationFailures adds the counter of the fetches of source, a
// list, the queries to it, a DNSBL zone, or the checks with it, AbuseIPDB,
// that failed, which count tells.
func (m *Metrics) addReputationFailures(source prometheus.Labels, count func() int) {
func (m *Metrics) addReputationFailures(
source prometheus.Labels,
count func() int,
) {
m.registry.MustRegister(prometheus.NewCounterFunc(prometheus.CounterOpts{
Name: "sww_reputation_failures_total",
Help: "Fetches of the list, queries to the DNSBL zone, or checks with " +
@@ -546,12 +603,17 @@ func statusClass(status int) string {
// counterVec returns a counter named name, described by help, with a
// series for each set of values of labels.
func counterVec(name, help string, labels []string) *prometheus.CounterVec {
return prometheus.NewCounterVec(prometheus.CounterOpts{Name: name, Help: help},
labels)
return prometheus.NewCounterVec(
prometheus.CounterOpts{Name: name, Help: help},
labels,
)
}
// gaugeVec returns a gauge named name, described by help, with a series
// for each set of values of labels.
func gaugeVec(name, help string, labels []string) *prometheus.GaugeVec {
return prometheus.NewGaugeVec(prometheus.GaugeOpts{Name: name, Help: help}, labels)
return prometheus.NewGaugeVec(
prometheus.GaugeOpts{Name: name, Help: help},
labels,
)
}