Documentation
¶
Overview ¶
Package stats collects Wireblast's traffic counters and turns them into periodic snapshots.
The split is deliberate: the transmit and receive loops touch nothing but a handful of per-queue atomic counters, and every bit of arithmetic, formatting and rate calculation happens in a separate collector goroutine. Nothing here is called from a packet hot path except Counters.AddTx and Counters.AddRx, which are a few atomic adds and no allocation.
The same Snapshot feeds the TUI dashboard and the --no-tui periodic output, so both report identical numbers.
Index ¶
- func Bits(v float64) string
- func Bytes(v uint64) string
- func Count(v uint64) string
- func Duration(d time.Duration) string
- func PPS(v float64) string
- type Class
- type Collector
- func (c *Collector) MarkStart()
- func (c *Collector) NumQueues() int
- func (c *Collector) Queue(i int) *Counters
- func (c *Collector) ResetInterval()
- func (c *Collector) Run(ctx context.Context, interval time.Duration)
- func (c *Collector) Sample() *Snapshot
- func (c *Collector) SetState(s State)
- func (c *Collector) Snapshot() *Snapshot
- func (c *Collector) State() State
- type Counters
- type HistoryPoint
- type Kernel
- type KernelFunc
- type KernelQueue
- type Option
- type Rates
- type Snapshot
- type State
- type Totals
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Count ¶
Count renders a packet or byte count compactly: 1234 -> "1.23 k", 14880000 -> "14.88 M". Small values are printed exactly, because "sent 7 packets" should say 7.
Types ¶
type Class ¶
type Class uint8
Class is the protocol bucket a packet is counted under. Classification is done by the generator (which already knows) on transmit, and by a minimal header peek on receive.
type Collector ¶
type Collector struct {
// contains filtered or unexported fields
}
Collector owns the per-queue counters and publishes snapshots.
func New ¶
New creates a collector for numQueues queues. kernel may be nil, in which case the kernel counters stay zero (useful in tests and before the fleet is open).
func (*Collector) MarkStart ¶
func (c *Collector) MarkStart()
MarkStart restarts the run clock as of now.
The dataplane calls this once the link is up. Attaching native XDP bounces the link for several seconds on many drivers, and counting that wait as part of the run would understate every average rate and make a 30-second run report 40 seconds.
func (*Collector) Queue ¶
Queue returns the counters for one queue. The dataplane hands each worker its own pointer at startup so the hot path never indexes a slice.
func (*Collector) ResetInterval ¶
func (c *Collector) ResetInterval()
ResetInterval zeroes the visible counters while leaving the lifetime totals untouched. This is the `r` hotkey.
func (*Collector) Run ¶
Run samples and publishes a snapshot every interval until ctx is cancelled. It publishes one final snapshot on the way out so the summary reflects the last packets sent.
func (*Collector) Sample ¶
Sample takes a reading now and publishes it. Run calls it on a ticker; the dataplane also calls it directly when it wants a fresh final snapshot.
func (*Collector) SetState ¶
SetState records what the run is doing; it shows up in the next snapshot.
type Counters ¶
type Counters struct {
TxPackets atomic.Uint64
TxBytes atomic.Uint64 // total Ethernet frame bytes, including the FCS
TxUDP atomic.Uint64
TxTCP atomic.Uint64
TxOther atomic.Uint64
TxErrors atomic.Uint64
RxPackets atomic.Uint64
RxBytes atomic.Uint64
RxUDP atomic.Uint64
RxTCP atomic.Uint64
RxOther atomic.Uint64
RxErrors atomic.Uint64
// contains filtered or unexported fields
}
Counters is one queue's counters. Each queue gets its own, so the transmit and receive loops never contend with each other.
The fields are atomic because the collector reads them concurrently, but they are only ever written by that queue's own goroutine.
type HistoryPoint ¶
HistoryPoint is one second of the run, kept so the dashboard can show where the rate has been rather than only where it is.
type Kernel ¶
type Kernel struct {
Queues int
RxPackets uint64
TxPackets uint64
RxDropped uint64
RxRingFull uint64
RxFillRingEmpty uint64
RxInvalidDescs uint64
TxInvalidDescs uint64
TxRingEmpty uint64
PerQueue []KernelQueue
}
Kernel holds the counters the AF_XDP library reports, copied into a library-independent shape so this package does not depend on go-afxdp (and so tests need no AF_XDP at all).
type KernelFunc ¶
KernelFunc reports the current kernel counters. It is injected so the collector can be tested without an AF_XDP fleet.
type KernelQueue ¶
type KernelQueue struct {
Queue int
RxPackets uint64
TxPackets uint64
RxDropped uint64
RxRingFull uint64
}
KernelQueue is one queue's slice of the kernel counters, used to point at a queue that is dropping or stalled.
type Option ¶
type Option func(*Collector)
Option configures a Collector.
func WithWindow ¶
WithWindow sets how many samples the rate average spans. With the default 250ms sampling interval, 4 samples means rates are averaged over a second and refreshed four times a second.
func WithoutTransmit ¶
func WithoutTransmit() Option
WithoutTransmit marks the run as receive-only, so the status line does not carry a transmit half that will only ever read zero.
type Rates ¶
type Rates struct {
PPS float64
// FrameBPS is **L2**: the Ethernet frame itself, including its 4-byte FCS.
//
// Note that the kernel's own netdev counters — what bwm-ng, iftop, nload
// and `ip -s link` report — exclude the FCS by specification, so they read
// 4 bytes per packet below this. That is about 6% at 64-byte frames and 1%
// at IMIX, and it is a different measurement rather than a disagreement.
FrameBPS float64
// WireBPS is **L1**: the frame plus the 20 bytes of physical framing every
// packet costs — 7-byte preamble, 1-byte start-frame delimiter and 12-byte
// interframe gap. This is link utilisation, and it is the unit --bps is
// measured in: 10G line rate means 10 Gbit/s of L1.
WireBPS float64
}
Rates are the per-second figures computed over the sampling window.
The two bit rates are the same two T-Rex reports, and are shown under those names: FrameBPS is L2, WireBPS is L1.
type Snapshot ¶
type Snapshot struct {
At time.Time
Elapsed time.Duration
Remaining time.Duration // 0 when the run has no duration limit
State State
// TX and RX are the visible counters, measured since the last interval
// reset. TotalTX and TotalRX are the lifetime figures, which the final
// summary reports and which an interval reset never disturbs.
TX, RX Totals
TotalTX, TotalRX Totals
TXRate, RXRate Rates
// IntervalSince is when the visible counters were last reset.
IntervalSince time.Time
Kernel Kernel
// Problems names queues that are dropping or stalled, ready to display.
Problems []string
// Transmits is false for a receive-only run, so the status line can leave
// out a transmit half that will only ever read zero.
Transmits bool
// History is one point per second, oldest first, for the dashboard's
// sparklines. It spans at most historyLen seconds.
History []HistoryPoint
}
Snapshot is an immutable view of the run, published by the collector and consumed by the TUI and the noninteractive printer.
type Totals ¶
type Totals struct {
Packets uint64
// Bytes is the total Ethernet frame size, including the 4-byte FCS — the
// same definition as --packet-size, so a run of 64-byte frames reports an
// average frame size of 64.
Bytes uint64
UDP uint64
TCP uint64
Other uint64
Errors uint64
Drops uint64
}
Totals is one direction's counters at a point in time.