Files
smallwebwaf/docs/metrics.md
T
sneak f74f25a51d
check / check (push) In progress
Say which bytes the byte limits count, and what passing one does (closes #203)
Documents only. The byte limits and byte anomaly thresholds count body
bytes, as SWW_BYTES_COUNT chooses them, with WebSocket traffic each way,
once a response has ended; the request that passes a limit is not cut
off and the client is banned. README.md, SPEC.md and docs/ now say so,
and no longer call a response's bytes the request's. Also made plain:
rate limits and their exemptions, the refusal threshold,
SWRP_MAX_REQUEST_TIME_MS, SWRP_MAX_RESPONSE_SIZE, SWW_LOOKUP_SOURCE,
SWW_LIMIT_BAN_REPEAT_WINDOW, the metrics' byte series, and the SPEC.md
claim about answering within SWRP_TIMEOUT_MS. EVALUATION.md is audited
too; its survey facts and date are unchanged.

Model: fable-5-1 (first audit); opus-5-5 (rework)
2026-11-09 02:06:20 +00: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_waf_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_geojs_unanswered_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_buffer_depth;
  • by destination, sww_alerts_sent_total, sww_alerts_failed_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.