monitor

package
v0.2.0 Latest Latest
Warning

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

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

Documentation

Overview

Package monitor observes the gateway without deciding anything: the bounded window of recent requests and its live views, request metrics, traffic summaries, the fixed advice checks, impact previews and the security log search.

It holds no authority over admission, policy, durable audit or upstream writes; every view is built from a generation, the observations or the security log files it is given. It has no HTTP routing and checks no permission: the Admin API does both. It imports only policy, compile and audit. The request pipeline records into it; the Admin API and the metrics listener read from it.

Index

Constants

View Source
const (
	AdviceRules = "checks-0.6"

	// The security log also raises an alert when, at the active file's recent
	// write rate, its remaining budget lasts less than FillingTime (medium) or
	// NearlyFullTime (critical). The rate is read over the file's last
	// RateMinBytes and counts once the file holds that much, so a few early
	// records cannot predict a fill and a slow start does not dilute it.
	FillingTime    = time.Hour
	NearlyFullTime = 15 * time.Minute
	RateMinBytes   = 1 << 20

	// NearlyFull is the share of a store that raises an alert; Filling, the
	// share of the security log budget that raises an earlier one.
	NearlyFull = 0.9
	Filling    = 0.7
)

The fixed checks, rule set version "checks-0.6": static configuration warnings, unused permissions from observed traffic, and alerts. They advise only: nothing here blocks, changes or activates anything, and nothing runs on the request path. Each answer names the rule set version so findings can be traced to the rules that made them.

View Source
const (
	PageScan   = 16 << 20
	ExportScan = 256 << 20
	ExportRows = 10000
)
View Source
const MaxStreams = 8
View Source
const QueueSize = 128
View Source
const TopLimit = 10

Variables

View Source
var ErrCursorGone = errors.New("the file the search stopped in is no longer present")

Functions

func EncodeCursor

func EncodeCursor(c Cursor) string

func LogFiles

func LogFiles(active string) (files, missing []string, err error)

LogFiles lists the audit files newest first: the active file, then the rotated files from the highest number down. missing names the numbered files below the highest that are no longer present (moved away to archive).

func Metrics

func Metrics(o *Observations, gauges func() []Gauge) http.Handler

Metrics serves the metrics listener from the observations and the published gauges, which published reads from the controller.

func OptionalString

func OptionalString(value string) *string

func Percentiles

func Percentiles(durations []float64) (float64, float64)

Percentiles returns the median and the 95th percentile of durations, which it sorts in place; both are zero when there are none.

func PreviewDecision

func PreviewDecision(g *compile.Generation, event Observed) (decision, code, operation string, known bool)

PreviewDecision shares canonical matching and permit evaluation with the request pipeline. It deliberately does not touch counters or validate bodies.

func RecentRecord added in v0.2.0

func RecentRecord(path string, span int64) (int64, time.Time, error)

RecentRecord finds the first complete record that starts at or after span bytes before the file's logical end (audit.End). It returns the bytes from that record to the end and the record's time; zero time when the file holds less than span or no complete, decodable record starts there. Besides audit.End's search, it reads at most two records.

func SortFindings

func SortFindings(items []Finding)

SortFindings gives the fixed order: severity, rule, object.

func TrafficTop

func TrafficTop[T any](items []T, count func(T) int, name func(T) string, limit int) []T

TrafficTop keeps the groups with the most requests, at most limit of them, ties broken by name so the order is stable between readings.

func WasAllowed

func WasAllowed(event RequestView) bool

traffic failures are refusals from the caller's perspective, while request events retain the distinction between refusal and an unknown upstream result.

Types

type Cursor

type Cursor struct {
	File   string `json:"f"`
	First  string `json:"i"`
	Offset int64  `json:"o"`
}

Cursor is where a search stopped: lines before offset in the file whose first record is first are still to be read. first identifies the file across a rotation, which renames the active file.

func DecodeCursor

func DecodeCursor(text string) *Cursor

type Finding

type Finding struct {
	ID       string `json:"id"`
	Severity string `json:"severity"`
	Object   string `json:"object"`
	Message  string `json:"message"`
}

func ConfigurationWarnings

func ConfigurationWarnings(g *compile.Generation, plain bool) []Finding

ConfigurationWarnings reads the compiled generation and, for HSTS, whether the gateway serves the data plane itself over plain HTTP (plain). A host program's listener may use TLS, which the gateway cannot see, so plain is false there and HSTS raises nothing.

func RefusalSpike

func RefusalSpike(events []Observed, now time.Time) *Finding

RefusalSpike applies the spike rule to the retained observations.

type Gauge added in v0.2.0

type Gauge struct {
	Name  string
	Value int64
}

Gauge is one gauge sample the metrics listener reports as read.

type LogUse

type LogUse struct {
	Searched []string
	// contains filtered or unexported fields
}

LogUse is what the security log shows about permission use: the role and endpoint pairs of allowed requests, how many request records were read and how far back they reach.

type Observations

type Observations struct {
	// contains filtered or unexported fields
}

Observations owns a bounded ring and bounded, nonblocking subscriptions. It has no authority over admission, policy, durable audit or upstream writes.

func New

func New(window, apis int) *Observations

New keeps the last window requests; apis bounds the per-API duration metrics. Both are the resolved capacity limits.

func (*Observations) Close

func (o *Observations) Close()

func (*Observations) Closing

func (o *Observations) Closing() <-chan struct{}

Closing closes when the observations close.

func (*Observations) ConnectionRefused added in v0.2.0

func (o *Observations) ConnectionRefused()

ConnectionRefused counts one data connection closed at the cap.

func (*Observations) Recent

func (o *Observations) Recent(keep func(*Observed) bool, limit int) []Observed

Recent returns, newest first, the retained requests that keep accepts, stopping once it has limit of them (0: no limit). Only returned requests are copied, so a reader that wants a short window or a few matches does not copy the whole ring while holding the lock the request path records under. keep runs under that lock and must not block.

func (*Observations) Record

func (o *Observations) Record(event audit.Event)

func (*Observations) Redirected added in v0.2.0

func (o *Observations) Redirected()

Redirected counts one answer of the HTTP-to-HTTPS redirect listener.

func (*Observations) Retained

func (o *Observations) Retained() int

Retained returns the number of requests kept in the window.

func (*Observations) RetainedSince

func (o *Observations) RetainedSince() (time.Time, bool)

RetainedSince returns the time of the oldest request still kept and whether older requests have already been dropped from the ring.

func (*Observations) Snapshot

func (o *Observations) Snapshot() []Observed

func (*Observations) Subscribe

func (o *Observations) Subscribe() *Viewer

func (*Observations) TakeDropped

func (o *Observations) TakeDropped(viewer *Viewer) uint64

func (*Observations) Unsubscribe

func (o *Observations) Unsubscribe(viewer *Viewer)

func (*Observations) Viewers

func (o *Observations) Viewers() int

Viewers returns the number of open live views.

func (*Observations) Window added in v0.2.0

func (o *Observations) Window() int

Window returns the number of requests the window keeps at most.

type Observed

type Observed struct {
	RequestView
	// contains filtered or unexported fields
}

func (Observed) ClaimedRoles

func (e Observed) ClaimedRoles() []string

ClaimedRoles are the verified role assertions, including roles the active policy dropped.

func (Observed) Sequence

func (e Observed) Sequence() uint64

Sequence is the request's position in the window, for paging.

type Query

type Query struct {
	// contains filtered or unexported fields
}

Query holds the filters of one search. Empty filters match all.

func ParseQuery

func ParseQuery(values map[string][]string) (Query, string)

type RequestView

type RequestView struct {
	RequestID     string    `json:"request_id"`
	Time          time.Time `json:"time"`
	Method        string    `json:"method"`
	Path          string    `json:"path"`
	Operation     *string   `json:"operation"`
	API           *string   `json:"api"`
	Subject       *string   `json:"subject"`
	Roles         []string  `json:"roles"`
	ClientAddress string    `json:"client_address"`
	Decision      string    `json:"decision"`
	Status        int       `json:"status"`
	Stage         string    `json:"stage"`
	Code          *string   `json:"code"`
	Generation    string    `json:"generation"`
	DurationMS    float64   `json:"duration_ms"`
	// Modules is present only in builds with modules other than the built-ins.
	Modules map[string]string `json:"modules,omitempty"`
}

RequestView is the explicit, secret-free Admin API projection. Private audit envelopes and their future fields are never serialized to viewers.

func View

func View(event audit.Event) RequestView

View is the secret-free view of a request's final audit event, shared by the live views and the security log search so both show the same fields.

type Result

type Result struct {
	Items      []RequestView
	Next       *Cursor
	Searched   []string
	Unreadable int
}
func Search(dir string, files []string, start *Cursor, query Query, limit int, scan int64) (Result, error)

Search reads the files in dir newest first from start, at most scan bytes, until limit records match. Only the final record of each request (request.rejected or request.forwarded) is read, as the live views do. A line still being written at the end of the active file is skipped.

type Summaries added in v0.2.0

type Summaries struct {
	// contains filtered or unexported fields
}

Summaries keeps the fileUse of each rotated file read in full, keyed by its name and checked against its size and modification time; rotated files do not change. An entry goes when its file is no longer listed. The zero value is ready to use.

func (*Summaries) PermitUse added in v0.2.0

func (c *Summaries) PermitUse(dir string, files []string, scan int64) (LogUse, error)

PermitUse reads the request records of the security log files, listed as LogFiles lists them (the active file first), newest first, at most scan bytes. A rotated file with a summary is not read but takes the budget its full read took, so the answer is the same as a full read's.

type TrafficGroup

type TrafficGroup struct {
	API       string  `json:"api"`
	Operation string  `json:"operation,omitempty"`
	Total     int     `json:"total"`
	Allowed   int     `json:"allowed"`
	Refused   int     `json:"refused"`
	P50       float64 `json:"p50_ms"`
	P95       float64 `json:"p95_ms"`
	// contains filtered or unexported fields
}

TrafficGroup counts the requests of one API or one endpoint and keeps their durations for the percentiles.

func (*TrafficGroup) Add

func (g *TrafficGroup) Add(event RequestView)

func (*TrafficGroup) Settle

func (g *TrafficGroup) Settle() TrafficGroup

type UnusedReport

type UnusedReport struct {
	Requests      int       `json:"requests"`
	Since         *string   `json:"since"`
	Complete      bool      `json:"complete"`
	FilesSearched []string  `json:"files_searched"`
	FilesMissing  []string  `json:"files_missing"`
	Withheld      *string   `json:"withheld"`
	Items         []Finding `json:"items"`
	MinMinute     int       `json:"min_minutes"`
	MinCount      int       `json:"min_requests"`
}

func UnusedPermissions

func UnusedPermissions(g *compile.Generation, use LogUse, missing []string, now time.Time) UnusedReport

UnusedPermissions lists permits no allowed request in the security log used, once the records read cover enough time and requests. missing names log files moved away, which were not read.

type Viewer

type Viewer struct {
	// contains filtered or unexported fields
}

func (*Viewer) Feed

func (v *Viewer) Feed() <-chan Observed

Feed delivers the viewer's requests.

Jump to

Keyboard shortcuts

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