Dashboard: notifier liveness from the heartbeat log
Replace the grep-docker-logs notifier panel with a per-node UP/DOWN stat driven by the app's new tag=heartbeat log line (count_over_time over 20m; 0 beats => DOWN/red). Update the README now that the app emits heartbeats.
This commit is contained in:
parent
710d9d4fec
commit
6137a08c23
2 changed files with 18 additions and 9 deletions
|
|
@ -110,7 +110,7 @@ curl -s 'http://10.10.0.2:3100/loki/api/v1/label/host/values' # -> {"data":["b
|
||||||
|
|
||||||
`Thermograph — Fleet Logs` (auto-provisioned), with a `Node` selector:
|
`Thermograph — Fleet Logs` (auto-provisioned), with a `Node` selector:
|
||||||
log volume by service, app error rate by tag, upstream 429 count, Caddy 5xx
|
log volume by service, app error rate by tag, upstream 429 count, Caddy 5xx
|
||||||
count, a notifier-liveness log panel, recent app errors, and a live all-container
|
count, a per-node notifier-liveness indicator (from the heartbeat log), recent app errors, and a live all-container
|
||||||
tail. Edit it in Grafana and re-export the JSON here to version a change.
|
tail. Edit it in Grafana and re-export the JSON here to version a change.
|
||||||
|
|
||||||
## Notes / follow-ups
|
## Notes / follow-ups
|
||||||
|
|
@ -118,6 +118,6 @@ tail. Edit it in Grafana and re-export the JSON here to version a change.
|
||||||
- **Loki is mesh-only** by design; only Grafana (with auth) is public.
|
- **Loki is mesh-only** by design; only Grafana (with auth) is public.
|
||||||
- Alloy reads the Docker socket read-only to discover containers.
|
- Alloy reads the Docker socket read-only to discover containers.
|
||||||
- Retention is 30 days on beta's disk — bump `loki/config.yml` if you want more.
|
- Retention is 30 days on beta's disk — bump `loki/config.yml` if you want more.
|
||||||
- Possible next step: have the app emit a periodic `notifier heartbeat` log line
|
- The app emits a `tag=heartbeat` line for the subscription notifier every
|
||||||
so notifier liveness is a first-class log-derived signal, not just container
|
~15m; the dashboard's "Notifier alive?" panel turns red if a node misses it.
|
||||||
chatter.
|
Extend the same `audit.log_heartbeat()` to any future background daemon.
|
||||||
|
|
|
||||||
|
|
@ -87,16 +87,25 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "logs",
|
"type": "stat",
|
||||||
"title": "Subscription notifier",
|
"title": "Notifier alive? (heartbeats / 20m, per node)",
|
||||||
"description": "Everything the app logs mentioning the notifier — its liveness at a glance.",
|
"description": "The subscription notifier logs a heartbeat every ~15m (tag=heartbeat). 0 beats in the last 20m on a node means its notifier is down.",
|
||||||
"gridPos": { "h": 4, "w": 12, "x": 12, "y": 8 },
|
"gridPos": { "h": 4, "w": 12, "x": 12, "y": 8 },
|
||||||
"datasource": { "type": "loki", "uid": "loki" },
|
"datasource": { "type": "loki", "uid": "loki" },
|
||||||
"options": { "showTime": true, "wrapLogMessage": true, "dedupStrategy": "exact", "sortOrder": "Descending" },
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"color": { "mode": "thresholds" },
|
||||||
|
"thresholds": { "mode": "absolute", "steps": [ { "color": "red", "value": null }, { "color": "green", "value": 1 } ] },
|
||||||
|
"mappings": [ { "type": "value", "options": { "0": { "text": "DOWN" } } } ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "background", "textMode": "value_and_name", "graphMode": "none" },
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"datasource": { "type": "loki", "uid": "loki" },
|
"datasource": { "type": "loki", "uid": "loki" },
|
||||||
"expr": "{job=\"docker\", service=\"app\", host=~\"$host\"} |~ \"(?i)notifier\""
|
"expr": "sum by (host) (count_over_time({job=\"app-json\", tag=\"heartbeat\", host=~\"$host\"} [20m]))",
|
||||||
|
"legendFormat": "{{host}}",
|
||||||
|
"instant": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue