packetlog

package
v0.13.3 Latest Latest
Warning

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

Go to latest
Published: May 9, 2026 License: GPL-2.0 Imports: 5 Imported by: 0

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 Direction

type Direction string

Direction labels a packet's flow.

const (
	DirRX Direction = "RX" // heard on the air
	DirTX Direction = "TX" // transmitted by us
	DirIS Direction = "IS" // APRS-IS upload/download (iGate)
)

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 New

func New(cfg Config) *Log

New builds an empty Log.

func (*Log) Capacity

func (l *Log) Capacity() int

Capacity returns the configured maximum.

func (*Log) Len

func (l *Log) Len() int

Len returns the current number of stored entries.

func (*Log) Query

func (l *Log) Query(f Filter) []Entry

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

func (l *Log) Record(e Entry)

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

func (l *Log) Stats() Stats

Stats returns a snapshot.

func (*Log) Subscribe added in v0.12.4

func (l *Log) Subscribe(ctx context.Context) <-chan Entry

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 Stats

type Stats struct {
	Entries  int
	Capacity int
}

Stats exposes gauges for metrics.

type SubscribeStats added in v0.12.4

type SubscribeStats struct {
	Subscribers int
	TotalDrops  uint64
}

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.

Jump to

Keyboard shortcuts

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