Skip to content
quarry Artifact [ab499e957a]
Login

Artifact [ab499e957a]

Artifact ab499e957a6da3a2c5dc97e59ec7e60a5670642dda4004c9965d20f60e936ac2:


package obs

import "time"

// TrafficRange is one of the windows the traffic page offers: how far
// back it reads, and how wide each point of its chart is.
type TrafficRange struct {
	Name string
	Span time.Duration
	Step time.Duration
}

// TrafficRanges are the windows, shortest first. Each is drawn in 60 to
// 168 points: fine enough that a burst of a few minutes shows as one,
// few enough that the chart stays a line rather than noise. The month
// is as far as the request log reaches (see obsduck.HitsKept).
var TrafficRanges = []TrafficRange{
	{"1h", time.Hour, time.Minute},
	{"24h", 24 * time.Hour, 10 * time.Minute},
	{"7d", 7 * 24 * time.Hour, time.Hour},
	{"30d", 30 * 24 * time.Hour, 6 * time.Hour},
}

// RangeNamed is the window by its name, the day for anything else.
func RangeNamed(name string) TrafficRange {
	for _, r := range TrafficRanges {
		if r.Name == name {
			return r
		}
	}
	return TrafficRanges[1]
}

// TrafficFilters are the page's filter chips. Every one narrows every
// panel; an empty one narrows nothing.
var TrafficFilters = []string{"repo", "kind", "network", "country", "path", "client", "crawler", "door"}

// TrafficQuery is what the page asks for.
type TrafficQuery struct {
	Range   TrafficRange
	Filters map[string]string
	// Now is the end of the window; zero is the present.
	Now time.Time
}

// TrafficTotals are the summary strip's numbers for one window.
type TrafficTotals struct {
	Visitors, Requests, Bytes, ServerMs, Errors int64
	// Automated is the share of requests from crawlers and scripts, 0..1.
	Automated float64
}

// TrafficPoint is one point of the chart.
type TrafficPoint struct {
	At time.Time
	// ByKind is requests by reader kind, in TrafficKinds order.
	ByKind   [4]int64
	Visitors int64
	Bytes    int64
	ServerMs int64
	Errors   int64
}

// TrafficKinds is the order ByKind and every kind breakdown use.
var TrafficKinds = [4]string{KindPerson, KindCrawler, KindAutomated, KindUnsure}

// Count is one bar of a breakdown.
type Count struct {
	Label string
	Note  string // the muted text beside the label
	N     int64
	// Key is what a filter chip set from this row filters on, when the
	// label is not it (an AS number behind a network's name).
	Key string
	// Flag marks a row worth a reader's eye: an impostor.
	Flag bool
}

// Latency is a path's or a kind's response times.
type Latency struct {
	Label        string
	N            int64
	P50Ms, P95Ms int64
}

// Download is one repository's reading by sync and archive.
type Download struct {
	Repo                     string
	Clones, Fetches, Archive int64
	Bytes                    int64
	// Mix is downloads by reader kind, in TrafficKinds order.
	Mix [4]int64
	// Zit, Fossil and Other split the sync rounds and archives by
	// client.
	Zit, Fossil, Other int64
	SignedIn           int64 // distinct verified accounts
}

// Source is one reader of downloads, grouped by who it appears to be.
type Source struct {
	Name string
	Kind string
	Took string // what it read: repositories and how
	N    int64
	Why  string // the evidence for Kind, in a sentence
}

// Traffic is everything the traffic page shows for one query.
type Traffic struct {
	Range      TrafficRange
	From, To   time.Time
	Totals     TrafficTotals
	Prev       TrafficTotals
	Points     []TrafficPoint
	PrevPoints []TrafficPoint

	Kinds     []Count
	Crawlers  []Count
	Networks  []Count
	Countries []Count
	Paths     []Count
	Slowest   []Latency
	Repos     []Count
	Served    []Count // bytes by what was served
	Status    []Count
	Referrers []Count
	Refused   []Count

	// Histogram counts responses by time: the edges are HistEdgesMs,
	// the last bucket everything past the last edge.
	Histogram     []int64
	P50, P95, P99 int64
	ByKind        []Latency

	// TimeSplit is where the server's time went, in milliseconds:
	// reading stores, the forge's own work around them, and rendering
	// and writing the response.
	StoreMs, LogicMs, RenderMs int64

	Downloads []Download
	How       []Count
	Sources   []Source
}

// HistEdgesMs are the response-time histogram's bucket edges.
var HistEdgesMs = []int64{5, 10, 20, 35, 50, 75, 100, 150, 200, 350, 500, 1000, 2000, 5000}

// Traffic reads the request log back for the traffic page. A forge with
// history switched off has none to read, and says so with a nil.
func (r *Recorder) Traffic(q TrafficQuery) (*Traffic, error) {
	r.mu.Lock()
	sink := r.sink
	r.mu.Unlock()
	t, ok := sink.(interface {
		Traffic(TrafficQuery) (*Traffic, error)
	})
	if !ok {
		return nil, nil
	}
	return r.traffic.get(q, time.Now(), t.Traffic)
}