edgeerr

package
v0.18.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

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

func RouteKey

func RouteKey(app, host, prefix string) string

RouteKey identifies a route (app + host + prefix).

Types

type Alerter

type Alerter interface {
	EnqueueInfra(ctx context.Context, o alert.Outbox) error
}

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) Ingest

func (c *Collector) Ingest(line []byte)

Ingest processes ONE raw access-log line (parse, then IngestRecord).

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 New

func New(path string) *Store

New opens (or creates) a store backed by path, loading any recent entries on disk.

func (*Store) Errors

func (s *Store) Errors(app, host, prefix, q string, limit int) []Entry

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

func (s *Store) Record(e Entry)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL