Documentation
¶
Overview ¶
Package edgeerr captures the managed edge's (Caddy's) ERROR responses — 4xx/5xx — per route, so an operator can see WHICH of an app's routes are erroring, when, and with what request, without tailing logs. It is fed by the same in-process access-log stream as the autoscaling metrics (attributed host+path → route via the HostIndex). Entries are the edge's view of the request (time, method, path, status, client IP, latency) — NOT the app's internal error text, which the edge never sees.
Bounded two ways so it can't grow without limit: a 24h TTL (older entries pruned) and a hard cap on the number of retained entries (oldest evicted first). Persisted to a JSONL file (atomic rewrite), SEPARATE from the single-conn SQLite DB (so it never contends with it), and reloaded on start.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Alerter ¶
Alerter is the subset of the alert store the collector needs (enqueue an infra alert). Kept as an interface so edgeerr doesn't depend on the concrete store (and stays trivially testable).
type Collector ¶
type Collector struct {
// contains filtered or unexported fields
}
Collector turns raw Caddy access-log lines into per-route error-log entries + the erroring-route alert. It shares the access-log stream with the autoscaling metrics collector (chained on the same hook). A line that doesn't parse, isn't an error (status < 400), or can't be attributed to a route is skipped — so hostile/garbage traffic and unmatched 404s are never recorded against a service.
func NewCollector ¶
func NewCollector(store *Store, idx *edgemetrics.HostIndex, alerts Alerter) *Collector
NewCollector wires the store + host index (+ optional alerter).
func (*Collector) IngestRecord ¶
func (c *Collector) IngestRecord(rec edgemetrics.AccessRecord)
IngestRecord records an ALREADY-PARSED access record — so a caller that also feeds the metrics collector can json-parse each access-log line only once. Non-error responses (< 400) and requests whose Host resolves to no route are dropped (never recorded against a service).
type Entry ¶
type Entry struct {
At int64 `json:"at"` // unix seconds
App string `json:"app"` // owning app (compose project)
Service string `json:"svc"` // service the route fronts
Host string `json:"host"` // route hostname
Prefix string `json:"prefix"` // route path prefix ("" = whole host)
Method string `json:"method"` // request method
Path string `json:"path"` // request path (query stripped)
Status int `json:"status"` // 4xx/5xx
RemoteIP string `json:"ip,omitempty"` // client IP
DurMs float64 `json:"dur_ms"` // latency (ms)
}
Entry is one edge-observed error response.
type ErrorBucket ¶ added in v0.18.0
type ErrorBucket struct {
T int64 `json:"t"` // bucket start (unix seconds)
Count int `json:"count"` // total 4xx + 5xx in the bucket
Count5xx int `json:"count5xx"` // server (5xx) errors only
}
ErrorBucket is one fixed time-window of a service's edge errors — the error-rate history series for the per-service metrics charts.
type RouteSummary ¶
type RouteSummary struct {
App, Service, Host, Prefix string
Count24h, CountHour int
Count5xx int
LastAt int64
LastStatus int
}
RouteSummary is one route's error rollup for the accordion header.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a bounded, TTL'd, file-backed edge-error log. Safe for concurrent use.
func (*Store) Errors ¶
Errors returns one route's error entries, newest first, optionally filtered by a case-insensitive substring across the rendered fields, capped at limit.
func (*Store) Flush ¶
func (s *Store) Flush()
Flush persists to disk if there are unsaved changes (called periodically by the owner).
func (*Store) RateBuckets ¶ added in v0.18.0
func (s *Store) RateBuckets(app, service string, bucketSecs, since int64) []ErrorBucket
RateBuckets returns one app+service's edge-error counts bucketed into fixed windows from `since` (unix seconds; <=0 or in the future ⇒ the full 24h TTL) to now, oldest first, aggregating ALL of the service's routes. Empty windows are returned as zeros so the series is continuous. Derived purely from the in-memory entries (no SQLite), like Routes.
func (*Store) Record ¶
Record appends one error entry (evicting the oldest if at the cap). Pruning by TTL is lazy (done in the read paths + Flush), keeping this off-the-hot-path O(1) amortized.
func (*Store) Routes ¶
func (s *Store) Routes() []RouteSummary
Routes returns each route that has errored within the TTL, most-recently-active first, with error counts (24h, last hour, 5xx) for the accordion.