Golectra is a tiny, self-hosted metrics stack in pure Go: a lightweight agent collects Go runtime + host metrics and ships them (gzipped JSON) to a server with a simple HTTP API and optional integrity checks.
- Agent samples Go runtime.MemStats + system metrics (CPU, RAM) via gopsutil.
- Gzipped JSON transport with automatic retries and rate-limited workers.
- Optional HashSHA256 header (HMAC-like) to protect request/response integrity.
- Storage: Postgres (auto-migrate) or in-memory with JSON file persistence & restore.
- HTTP API (Gin) + a quick HTML dashboard at / (tables of gauges/counters).
- Zero deps at runtime (server/agent binaries). Go 1.21+.
- Run the server
go run ./cmd/server -a :8080 -f metrics-db.json -i 300
# Flags:
# -a listen address, -f file path for snapshots, -i store interval seconds (0 = sync)- Run the agent
go run ./cmd/agent -a http://localhost:8080 -r 10 -p 2 -l 2
# -r report interval (s), -p poll interval (s), -l parallel sendersOpen http://localhost:8080 to see metrics.
Path params:
- Update one (plain text):
POST /update/:type/:name/:valuewheretypeisgaugeorcounter - Read one (plain text):
GET /value/:type/:name - Read HTML dashboard:
GET / - JSON (recommended):
# Upsert one
curl -X POST http://localhost:8080/update \
-H "Content-Type: application/json" \
-d '{"id":"Alloc","type":"gauge","value":12345}'
# Read one
curl -X POST http://localhost:8080/value \
-H "Content-Type: application/json" \
-d '{"id":"Alloc","type":"gauge"}'
# Upsert batch
curl -X POST http://localhost:8080/updates \
-H "Content-Type: application/json" \
-d '[{"id":"foo","type":"gauge","value":1.23},{"id":"bar","type":"counter","delta":7}]'
# Health
curl http://localhost:8080/pingStart both server and agent with the same secret key (-k or KEY env). The server will validate HashSHA256 for incoming POST bodies and will always set a HashSHA256 response header.
Example with curl:
BODY='{"id":"temp","type":"gauge","value":42}'
KEY='your-secret'
HASH=$(printf '%s' "$BODY$KEY" | openssl dgst -sha256 -binary | xxd -p -c 256)
curl -X POST http://localhost:8080/update \
-H "Content-Type: application/json" \
-H "HashSHA256: $HASH" \
-d "$BODY" -iSet --audit-file /path/to/audit.ndjson (or AUDIT_FILE) to append newline-delimited JSON events locally, --audit-url https://audit.example.com/hook (or AUDIT_URL) to POST events to a remote service, or enable both. Each successful metrics write triggers a fan-out notification to every configured sink via the Observer pattern, using this payload:
{
"ts": 1735584000,
"metrics": ["Alloc", "PollCount"],
"ip_address": "192.168.0.42"
}Delivery failures are logged but never bubble up to the HTTP handlers, so metric ingestion stays available even if an audit sink is down.
You can use ENV, CLI flags, or defaults (ENV > CLI > defaults).
| Setting | ENV | Flag | Default | Notes |
|---|---|---|---|---|
| Address | ADDRESS |
-a |
:8080 |
host:port |
| File storage | FILE_STORAGE_PATH |
-f |
metrics-db.json |
JSON snapshot file |
| Postgres DSN | DATABASE_DSN |
-d |
empty | e.g. postgres://user:pass@localhost:5432/db?sslmode=disable |
| Secret key | KEY |
-k |
empty | enables HashSHA256 |
| Store interval | STORE_INTERVAL |
-i |
300s |
0 = sync writes |
| Restore on start | RESTORE |
-r |
false |
load from file at boot |
| Audit file | AUDIT_FILE |
--audit-file |
empty | newline-delimited JSON audit log fan-out target (disabled when empty) |
| Audit URL | AUDIT_URL |
--audit-url |
empty | HTTP POST endpoint for audit events (disabled when empty) |
| Setting | ENV | Flag | Default | Notes |
|---|---|---|---|---|
| Server address | ADDRESS |
-a |
http://localhost:8080 |
URL or host:port |
| Secret key | KEY |
-k |
empty | adds HashSHA256 |
| Report interval | REPORT_INTERVAL |
-r |
10s |
send frequency |
| Poll interval | POLL_INTERVAL |
-p |
2s |
sample frequency |
| Rate limit | RATE_LIMIT |
-l |
1 |
concurrent send workers |
Go runtime gauges like Alloc, HeapAlloc, NumGC, PauseTotalNs, plus host gauges TotalMemory, FreeMemory, and per-core CPUutilization{N}; counters include PollCount, etc.