# Status Tracker
A simple self-hosted service status tracker.
## Requirements
- C++
- User Cmake to build.
- All external dependencies should be pulled using `FetchContent`,
except for basic ones like OpenSSL, SQLite, etc. `FetchContent`
should not pin to specific version of these dependencies. But some
dependencies may need a branch specified.
- No authentication. The web UI is read-only and data-driven.
- YAML configuration
- It monitors a bunch of endpoints which are defined in the
config file
- Endpoints may be monitored by one of the following protocols:
* HTTP (check it returns 2xx status)
* TCP or UDP port open
* ICMP
- Possible config snippet for endpoint:
```yaml
some-endpoint-id: # A uniq ID
name: Blog
description: It’s my blog.
# User-facing URL
url: https://blog.mws.rocks/
endpoint:
# Different protocols may have different set of fields.
protocol: HTTP
# This could be different from the user-facing URL. If this is omitted, use the user-facing URL
url: https://blog.mws.rocks/
timeout_second: 5
interval:
value: 1
unit: minute
```
Another:
```yaml
some-endpoint-id: # A uniq ID
name: VM host
description: My VM host
endpoint:
protocol: ICMP
host: 10.10.10.20
timeout_second: 5
interval:
value: 1
unit: minute
```
- In the config file the endpoints are grouped with another level of
grouping. This grouping is also shown in the web UI.
- Stores status history in SQLite db.
- Endpoint status: There should be four possible status: good, bad,
other, and n/a. Right now we can reserve “other” for the case where
UDP probe does not get a response. “N/a” is the case where there is
no data in the database (which is different from the service being
unavailable) or data is staled (the last data point is more than
twice the interval old). These status should be indicated on
the webpage with a “LED light”. Good is green, bad is red, other is
yellow, n/a is dimmed light.
- In the database, each status update has:
* Service ID (the uniq ID defined in the config)
* Timestamp with precision to a second (UTC unix timestamp)
* Duration in microseconds (the time it takes to finish the status
check)
* Status (integer)
## Probe scheduling
- Probe workflow:
1. A priority queue of tasks, ordered by next due time.
2. Each endpoint has an atomic bool `in_flight`.
3. The scheduler dequeue a task, If no worker is available, ditch
the task. If there is a worker available, if the endpoint is
already inflight, ditch the task; otherwise mark the endpoint as
inflight, and dispatch it to a worker.
4. The scheduler enqueue the next task of that endpoint. Note that
if the schedued time of the next task is in the past, we should
find the next one that’s in the future.
5. The scheduler peeks the queue and wait for the next task to
trigger.
6. Meanwhile the worker does the probing, and save the result to db
7. worker marks the endpoint as not inflight.
- Each worker is a thread in a thread pool with a fixed capacity. The
capacity is defined in the config file.
## UI
- Server-rendered HTML
- No live updates. The user should referesh if they want new data
- Use Inja for templates
- Templates and static files are compiled into the binary at build
time. In the repository they are individual files in the file
system.