Files
smallwebwaf/docs/metrics.md
clawbot 719691d1e8
check / check (push) Failing after 3m22s
Name log fields, metrics and the Core Rule Set package for what they are (closes #192)
The first half of the naming audit: names now say what they are. `internal/waf` is `internal/coreruleset`. Log fields, the action `blocked_by_core_rule_set`, the metric and the alert event say Core Rule Set. Timings end `_ms`. Percentages say of what, as `rate_limit_percent` and `bytes_limit_percent`. Setting names follow in #234.

Judgement call: `blocked_by_core_rule_set`, not the audit's `core_rule_set_blocked`, to match `blocked_by_block_rule`.
Trips a reader: an existing state file holding `waf_blocked` or the anomaly scope `watch` stops the start and must be removed. `SWW_ALERT_EVENTS` listing `waf_block` must list `core_rule_set_match`.

Model: opus-5-5
2026-11-09 08:47:26 +01:00

3.2 KiB

The metrics

What GET /_sww/metrics answers with, at discriminator's own address. "Metrics endpoint" in SPEC.md describes the endpoint. Prometheus keeps the instance label as exported_instance unless the scrape sets honor_labels: true. rproxy has no metrics.

Every sww_*request_bytes_total and sww_*response_bytes_total series counts body bytes, never headers, whatever SWW_BYTES_COUNT says.

Traffic

  • sww_requests_total, sww_request_bytes_total and sww_response_bytes_total, by status_class such as 2xx and by action;
  • sww_request_duration_seconds and sww_upstream_duration_seconds, as histograms;
  • sww_requests_in_flight: the questions and requests to its own endpoints that discriminator is handling.

Limits and bans

  • sww_rate_limit_hits_total, by window and by kind (requests, bytes or refusals);
  • sww_offences_total, by kind;
  • sww_bans_made_total, by cause;
  • sww_active_bans and sww_permanent_bans.

Attack detection

  • sww_rule_matches_total, by rule_id and action, and sww_rules_loaded;
  • sww_core_rule_set_matches_total, by mode and rule_id, for the rules that fired.

Countries and AS numbers

For the SWW_METRICS_TOP_N busiest of each, the rest as other:

  • sww_country_requests_total, sww_country_request_bytes_total, sww_country_response_bytes_total and sww_country_list_refusals_total, by country;
  • sww_asn_requests_total, sww_asn_request_bytes_total and sww_asn_response_bytes_total, by asn.

Lookups

  • sww_geojs_requests_total and sww_geojs_failures_total;
  • sww_requests_without_geojs_answer_total: the requests that needed an answer and went on without it;
  • with the file source, sww_lookup_database_last_read_timestamp_seconds and sww_lookup_database_read_failures_total.

Reputation sources

By source: each list's URL, each zone, and abuseipdb:

  • sww_reputation_hits_total, sww_reputation_queries_total and sww_reputation_failures_total;
  • sww_reputation_last_fetch_timestamp_seconds, for a list;
  • sww_reputation_daily_budget_remaining, for AbuseIPDB.

State files

By file:

  • sww_state_file_writes_total, sww_state_file_write_failures_total, sww_state_file_last_write_timestamp_seconds and sww_state_file_size_bytes;
  • sww_state_file_edits_taken_in_total and sww_state_file_edits_set_aside_total;
  • sww_tracked_clients: the clients in the table.

Remote log, alerts and the process

  • while a syslog server is set, sww_remote_log_lines_sent_total, sww_remote_log_lines_dropped_total and sww_remote_log_lines_waiting;
  • by destination, sww_alerts_sent_total, sww_alert_send_failures_total, sww_alerts_suppressed_total and sww_alerts_dropped_total;
  • Go's own go_ metrics and the process's process_ metrics.

When a request is counted

discriminator counts a denied request at its decision, and a request to its own endpoints when it is answered. It counts an allowed request when its report comes, with the status, bytes and times the report gives. These are not counted:

  • a report itself;
  • an allowed request whose report never comes;
  • a question refused with 400;
  • a question whose body stopped arriving.