Metrics
The server publishes Prometheus metrics at GET /metrics on its API listener (listen.address
and/or listen.tlsAddress). The numbers are the server's own statistics, read when Prometheus
scrapes, so they always match GET /api/v1/flows/{id}/stats?lifetime=true.
/metrics needs credentials of a user with flows:view. It does not need the
X-Weavster-CSRF header, so a plain Prometheus scrape works:
# prometheus.yml
scrape_configs:
- job_name: weavster
scheme: https
static_configs:
- targets: ["weavster.internal:8443"]
basic_auth:
username: prometheus
password_file: /etc/prometheus/weavster-password
Create a user with only flows:view for Prometheus, and send "mustChangePassword": false so
it can sign in with the password you gave it (otherwise every scrape gets
403 PASSWORD_CHANGE_REQUIRED until the password is changed; see
Authentication):
curl -s -u 'admin:PASSWORD' -H 'X-Weavster-CSRF: 1' -X POST http://127.0.0.1:8080/api/v1/users \
-d '{"username":"prometheus","password":"A-Long-Scrape-Pass1","permissions":["flows:view"],"mustChangePassword":false}'
A scrape without credentials gets 401 and is recorded in the audit log as
auth.failure.
curl -s -u 'prometheus:PASSWORD' https://weavster.internal:8443/metrics | grep '^weavster_'
weavster_connector_messages_total{connector="ehr",flow="adt",outcome="errored"} 1
weavster_connector_messages_total{connector="ehr",flow="adt",outcome="sent"} 120
weavster_flow_messages_total{flow="adt",outcome="received"} 121
weavster_flow_messages_total{flow="adt",outcome="sent"} 120
weavster_flows{status="started"} 3
weavster_processing_in_flight 0
weavster_processing_refused_total 0
weavster_processing_slots 32
What is published
| Metric | Type | Labels | Meaning |
|---|---|---|---|
weavster_flow_messages_total |
counter | flow, outcome |
A flow's messages by outcome: received, filtered, transformed, sent, queued, errored. |
weavster_connector_messages_total |
counter | flow, connector, outcome |
Deliveries to a flow's destination (connector, the destination's name): sent, or errored for every failed attempt (retries included). |
weavster_flows |
gauge | status |
Flows in each lifecycle status (started, stopped, undeployed, …). |
weavster_processing_in_flight |
gauge | Messages from the API and flow sources being received and processed right now. Retries of queued messages and hand-offs from one flow to another take no slot and are not counted. | |
weavster_processing_slots |
gauge | How many can be at once (processing.maxConcurrent). |
|
weavster_processing_refused_total |
counter | Messages refused as busy because every slot was taken. | |
go_*, process_* |
The Go runtime and the process (memory, goroutines, open files; which process_* metrics exist depends on the operating system). |
The counters are the lifetime statistics. Every flow is published, with zeros before its first
message; a deleted flow's series go away. The counters start at zero when the server starts and go
back to zero when you reset them (POST /api/v1/flows/stats/reset?lifetime=true); Prometheus
treats that as a counter reset, so rate() and increase() stay correct.
A message counts queued once, when its first delivery fails, and sent once it is delivered;
each failed attempt in between counts in weavster_connector_messages_total{outcome="errored"}.
Watch that, not queued, for a destination that keeps failing. Without a message store
(store.dialect: disabled) the weavster_processing_* metrics are not published. Each scrape
reads the flow list from the store; if that fails, the flow metrics are left out of that scrape
and the server logs metrics: flows could not be listed.