Documentation
¶
Overview ¶
Package packetlog is a bounded in-memory ring buffer of RX/TX/IS packet records with a filtered query API. Other packages register as hooks via the Hook interface and every subsystem on the packet path (modembridge RX, txgovernor TX, iGate IS upload) funnels through a single Log instance so the web UI and REST API can render a unified packet stream.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Capacity is the maximum number of entries retained. Default 1000.
Capacity int
// MaxAge bounds how old entries can be before GC. Default 30 minutes.
// Entries are pruned lazily on Record and on Query.
MaxAge time.Duration
}
Config tunes a Log.
type Entry ¶
type Entry struct {
// Timestamp is the UTC RFC3339 time the packet was recorded.
Timestamp time.Time `json:"timestamp"`
// Channel is the graywolf channel ID that observed or transmitted the packet.
Channel uint32 `json:"channel"`
// Direction labels the flow: "RX" (heard on air), "TX" (transmitted by us), or "IS" (APRS-IS upload/download).
Direction Direction `json:"direction"`
// Source identifies the subsystem that produced this entry: "kiss", "agw", "digi", "igate-tx", "beacon", "modem", or "igate-is".
Source string `json:"source"`
// Raw is the on-air AX.25 frame bytes with FCS stripped; omitted for entries without raw framing.
Raw []byte `json:"raw,omitempty"`
// Display is a direwolf-style human-readable rendering: "SRC>DEST[,DIGI*]:info".
Display string `json:"display"`
// Type is the APRS packet type (position, message, status, ...) when the payload decoded successfully.
Type string `json:"type,omitempty"`
// Decoded is the parsed APRS payload when decoding succeeded; nil otherwise.
Decoded *aprs.DecodedAPRSPacket `json:"decoded,omitempty"`
// Notes is a short annotation describing how this entry was handled (e.g. "deduped", "rate-limited", "digi consumed WIDE1-1").
Notes string `json:"notes,omitempty"`
}
Entry is one recorded packet.
type Filter ¶
type Filter struct {
Since time.Time // zero = no lower bound
Source string // empty = any
Type string // empty = any; matches Entry.Type
Direction Direction // empty = any
Channel int // -1 = any; otherwise match Channel exactly
Limit int // <=0 = no cap (beyond ring size)
}
Filter narrows a Query.
type Hook ¶
type Hook interface {
Record(e Entry)
}
Hook lets other packages record packets into the log without taking a hard dependency on *Log's concrete type.
type Log ¶
type Log struct {
// contains filtered or unexported fields
}
Log is a thread-safe ring buffer of Entry values with a time-limited retention window.
func (*Log) Query ¶
Query returns entries matching f in chronological order (oldest first). A copy is made under the lock so callers can iterate without holding it.
func (*Log) Record ¶
Record inserts e into the ring, evicting the oldest entry if full. Safe for concurrent use. Zero-valued Timestamp is filled in with now.
func (*Log) Subscribe ¶ added in v0.12.4
Subscribe returns a channel that receives every Entry recorded after the call until ctx is cancelled. The channel is closed when the subscription ends (ctx done OR the Log is closed). The non-blocking fanout drops on slow consumers and bumps a per-subscriber counter so callers can detect the loss; total drops are exposed via SubscribeStats.
Subscribe never replays existing buffered entries -- callers that need historical context must call Query first, then Subscribe for tail.
Multiple subscribers are independent; each gets its own channel.
func (*Log) SubscribeStats ¶ added in v0.12.4
func (l *Log) SubscribeStats() SubscribeStats
SubscribeStats returns a snapshot of the fanout state.
type SubscribeStats ¶ added in v0.12.4
SubscribeStats reports an aggregate snapshot of all live subscribers. Used by /metrics or test assertions to detect ongoing drops without having to track each subscriber individually.