Documentation
¶
Overview ¶
Package analytics provides terminal escape code extraction and analysis
Index ¶
- func DescribeSGR(params string) string
- func DescribeSimpleEscape(secondByte byte) string
- func GetDECPrivateModeDescription(mode string) string
- func GetEraseInDisplayDescription(params string) string
- func GetEraseInLineDescription(params string) string
- func GetOSCDescription(cmd string) string
- func SetGlobalEscapeWriter(w EscapeEventWriter)
- type EscapeCategory
- type EscapeCodeEntry
- type EscapeCodeParser
- func (p *EscapeCodeParser) GetStats() ParserStats
- func (p *EscapeCodeParser) IsEnabled() bool
- func (p *EscapeCodeParser) Parse(data []byte, sessionSeq int64) []byte
- func (p *EscapeCodeParser) ParseStage2(data []byte, sessionSeq int64)
- func (p *EscapeCodeParser) RunCorrelatorEviction(ctx context.Context)
- func (p *EscapeCodeParser) SetCorrelator(c *MangleCorrelator)
- func (p *EscapeCodeParser) SetEnabled(enabled bool)
- func (p *EscapeCodeParser) SetEventWriter(w EscapeEventWriter, captureLevel string, redactOSC bool, samplingRate float64)
- func (p *EscapeCodeParser) SetStableSessionID(id string)
- type EscapeCodeStats
- type EscapeCodeStore
- func (s *EscapeCodeStore) Clear()
- func (s *EscapeCodeStore) Export() ([]byte, error)
- func (s *EscapeCodeStore) GetAll() []EscapeCodeEntry
- func (s *EscapeCodeStore) GetByCategory(category EscapeCategory) []EscapeCodeEntry
- func (s *EscapeCodeStore) GetBySession(sessionID string) []EscapeCodeEntry
- func (s *EscapeCodeStore) GetStats() EscapeCodeStats
- func (s *EscapeCodeStore) IsEnabled() bool
- func (s *EscapeCodeStore) Record(sessionID string, rawBytes []byte, category EscapeCategory, description string)
- func (s *EscapeCodeStore) SetEnabled(enabled bool)
- type EscapeEventRecord
- type EscapeEventWriter
- type MangleCorrelator
- func (c *MangleCorrelator) CheckStage2(sessionID, sequenceType, hash string, byteLen int) (bool, string)
- func (c *MangleCorrelator) EvictExpired(ctx context.Context, writer EscapeEventWriter)
- func (c *MangleCorrelator) PendingCount() int
- func (c *MangleCorrelator) RecordStage1(sessionID, sequenceType, hash string, byteLen int)
- func (c *MangleCorrelator) StartEviction(ctx context.Context, writer EscapeEventWriter)
- type NoopEscapeEventWriter
- type ParsedEscapeCode
- type ParserStats
- type Stage
- type Stage1Observation
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DescribeSGR ¶
DescribeSGR returns a human-readable description of SGR parameters
func DescribeSimpleEscape ¶
DescribeSimpleEscape returns a description for a simple 2-byte escape
func GetDECPrivateModeDescription ¶
GetDECPrivateModeDescription returns a human-readable description for a DEC private mode
func GetEraseInDisplayDescription ¶
Erase in Display descriptions
func GetEraseInLineDescription ¶
Erase in Line descriptions
func GetOSCDescription ¶
GetOSCDescription returns a human-readable description for an OSC command
func SetGlobalEscapeWriter ¶
func SetGlobalEscapeWriter(w EscapeEventWriter)
SetGlobalEscapeWriter replaces the process-wide escape event writer. Called once at server startup after the batch writer is created.
Types ¶
type EscapeCategory ¶
type EscapeCategory string
EscapeCategory represents the type of escape sequence
const ( CategoryCSI EscapeCategory = "CSI" // Control Sequence Introducer \x1b[ CategoryOSC EscapeCategory = "OSC" // Operating System Command \x1b] CategoryDCS EscapeCategory = "DCS" // Device Control String \x1bP CategoryPM EscapeCategory = "PM" // Privacy Message \x1b^ CategoryAPC EscapeCategory = "APC" // Application Program Command \x1b_ CategorySOS EscapeCategory = "SOS" // Start of String \x1bX CategoryC1 EscapeCategory = "C1" // C1 control codes CategorySimple EscapeCategory = "Simple" // Simple 2-char escapes CategoryDECPriv EscapeCategory = "DECPriv" // DEC Private modes \x1b[? CategorySGR EscapeCategory = "SGR" // Select Graphic Rendition (colors/styles) CategoryCursor EscapeCategory = "Cursor" // Cursor positioning CategoryErase EscapeCategory = "Erase" // Screen/line erase CategoryScroll EscapeCategory = "Scroll" // Scroll region CategoryCharset EscapeCategory = "Charset" // Character set selection CategoryUnknown EscapeCategory = "Unknown" // Unknown sequence )
type EscapeCodeEntry ¶
type EscapeCodeEntry struct {
Code string `json:"code"` // Hex-encoded sequence
HumanReadable string `json:"humanReadable"` // Description
Category EscapeCategory `json:"category"` // Type of sequence
Count int64 `json:"count"` // How many times seen
FirstSeen time.Time `json:"firstSeen"` // First occurrence
LastSeen time.Time `json:"lastSeen"` // Most recent occurrence
SessionIDs []string `json:"sessionIds"` // Sessions that produced this code
}
EscapeCodeEntry represents a tracked escape sequence
type EscapeCodeParser ¶
type EscapeCodeParser struct {
// contains filtered or unexported fields
}
EscapeCodeParser extracts escape sequences from terminal output
func NewEscapeCodeParser ¶
func NewEscapeCodeParser(store *EscapeCodeStore, sessionID string) *EscapeCodeParser
NewEscapeCodeParser creates a new parser with the given store and session ID
func (*EscapeCodeParser) GetStats ¶
func (p *EscapeCodeParser) GetStats() ParserStats
GetStats returns lifetime counters for this parser.
func (*EscapeCodeParser) IsEnabled ¶
func (p *EscapeCodeParser) IsEnabled() bool
IsEnabled returns whether parsing is enabled
func (*EscapeCodeParser) Parse ¶
func (p *EscapeCodeParser) Parse(data []byte, sessionSeq int64) []byte
Parse extracts all escape sequences from data and records them to the store. sessionSeq is the cumulative PTY byte offset at the start of this chunk. Returns the original data unchanged (passthrough).
func (*EscapeCodeParser) ParseStage2 ¶
func (p *EscapeCodeParser) ParseStage2(data []byte, sessionSeq int64)
ParseStage2 performs a secondary parse pass over data (a coalesced transport frame) and emits EscapeEventRecord entries with Stage=StageTransport. sessionSeq is the cumulative transport byte offset at the start of this frame. ParseStage2 uses its own independent chunk counter (stage2ChunkSeqNum) for sampling so that calling it independently does not interfere with the Stage 1 counter.
func (*EscapeCodeParser) RunCorrelatorEviction ¶
func (p *EscapeCodeParser) RunCorrelatorEviction(ctx context.Context)
RunCorrelatorEviction runs the attached correlator's eviction loop until ctx is cancelled. No-op if no correlator or writer is configured (e.g. capture_level=off). Blocks the calling goroutine — callers that need this to run in the background must launch it themselves (e.g. `go p.RunCorrelatorEviction(ctx)`, ideally tracked with the same WaitGroup used for their other background work so a "Stop" method can block until this has actually exited too). Recovers from panics so a bug here can't take down the whole process.
func (*EscapeCodeParser) SetCorrelator ¶
func (p *EscapeCodeParser) SetCorrelator(c *MangleCorrelator)
SetCorrelator attaches a MangleCorrelator to this parser for Stage 1/2 mangle detection.
func (*EscapeCodeParser) SetEnabled ¶
func (p *EscapeCodeParser) SetEnabled(enabled bool)
SetEnabled enables or disables escape code parsing
func (*EscapeCodeParser) SetEventWriter ¶
func (p *EscapeCodeParser) SetEventWriter(w EscapeEventWriter, captureLevel string, redactOSC bool, samplingRate float64)
SetEventWriter configures the event writer and capture settings.
func (*EscapeCodeParser) SetStableSessionID ¶
func (p *EscapeCodeParser) SetStableSessionID(id string)
SetStableSessionID overrides the session identifier recorded on emitted events. Used to switch from the tmux session name (used at construction time) to the stable session UUID once it is known, so escape_event rows can be correlated with the same session identifier the rest of the app uses. Safe to call at any time, including concurrently with Parse/ParseStage2 on a running stream — the name matches ResponseStream.SetStableSessionID, which wraps it, so both ends of this wiring are textually distinguishable from tmux-name-keyed setters (like detection.StatusDetector.SetSessionID) called nearby at the same call site.
type EscapeCodeStats ¶
type EscapeCodeStats struct {
Enabled bool `json:"enabled"`
TotalCodes int64 `json:"totalCodes"` // Total codes recorded
UniqueCodes int `json:"uniqueCodes"` // Unique sequences
CategoryCounts map[EscapeCategory]int64 `json:"categoryCounts"` // Count by category
TopCodes []EscapeCodeEntry `json:"topCodes"` // Most frequent codes
RecentCodes []EscapeCodeEntry `json:"recentCodes"` // Recently seen codes
}
EscapeCodeStats provides aggregated statistics
type EscapeCodeStore ¶
type EscapeCodeStore struct {
// contains filtered or unexported fields
}
EscapeCodeStore provides thread-safe storage for escape code analytics
func GetGlobalStore ¶
func GetGlobalStore() *EscapeCodeStore
GetGlobalStore returns the singleton escape code store
func NewEscapeCodeStore ¶
func NewEscapeCodeStore() *EscapeCodeStore
NewEscapeCodeStore creates a new store with default settings
func (*EscapeCodeStore) Export ¶
func (s *EscapeCodeStore) Export() ([]byte, error)
Export returns all data as JSON
func (*EscapeCodeStore) GetAll ¶
func (s *EscapeCodeStore) GetAll() []EscapeCodeEntry
GetAll returns all entries
func (*EscapeCodeStore) GetByCategory ¶
func (s *EscapeCodeStore) GetByCategory(category EscapeCategory) []EscapeCodeEntry
GetByCategory returns entries for a specific category
func (*EscapeCodeStore) GetBySession ¶
func (s *EscapeCodeStore) GetBySession(sessionID string) []EscapeCodeEntry
GetBySession returns entries for a specific session
func (*EscapeCodeStore) GetStats ¶
func (s *EscapeCodeStore) GetStats() EscapeCodeStats
GetStats returns aggregated statistics
func (*EscapeCodeStore) IsEnabled ¶
func (s *EscapeCodeStore) IsEnabled() bool
IsEnabled returns whether tracking is enabled
func (*EscapeCodeStore) Record ¶
func (s *EscapeCodeStore) Record(sessionID string, rawBytes []byte, category EscapeCategory, description string)
Record adds or updates an escape code entry
func (*EscapeCodeStore) SetEnabled ¶
func (s *EscapeCodeStore) SetEnabled(enabled bool)
SetEnabled enables or disables tracking
type EscapeEventRecord ¶
type EscapeEventRecord struct {
SessionID string
Stage Stage
SequenceType string // "CSI", "OSC", "DCS", etc.
SequenceSubtype string // e.g. "SGR", "cursor-up", "clipboard"
ByteLen int
PayloadHash string // SHA-256 hex prefix, empty if redacted
RawBytes []byte // nil unless capture_level=full
Mangled bool
MangleType string // "truncated", "mutated", "stripped"
WallTime time.Time
SessionSeq int64 // cumulative PTY byte offset at start of chunk
}
EscapeEventRecord holds a single observed escape sequence event.
type EscapeEventWriter ¶
type EscapeEventWriter interface {
WriteEscapeEvent(ctx context.Context, event EscapeEventRecord)
}
EscapeEventWriter is the interface for persisting escape events.
func GetGlobalEscapeWriter ¶
func GetGlobalEscapeWriter() EscapeEventWriter
GetGlobalEscapeWriter returns the process-wide escape event writer.
type MangleCorrelator ¶
type MangleCorrelator struct {
// contains filtered or unexported fields
}
func NewMangleCorrelator ¶
func NewMangleCorrelator(maxAge time.Duration, maxSize int) *MangleCorrelator
NewMangleCorrelator creates a correlator with the given TTL and max pending size.
func (*MangleCorrelator) CheckStage2 ¶
func (c *MangleCorrelator) CheckStage2(sessionID, sequenceType, hash string, byteLen int) (bool, string)
CheckStage2 checks whether the next Stage 2 observation for this (sessionID, sequenceType) pair — the next ordinal — matches its corresponding Stage 1 observation. Returns (mangled bool, mangleType string). mangleType is one of: "", "truncated", "mutated". If no Stage 1 observation is found at that ordinal, returns (false, "") — absence is not definitive; the eviction pass handles the "never arrived" (stripped) case.
func (*MangleCorrelator) EvictExpired ¶
func (c *MangleCorrelator) EvictExpired(ctx context.Context, writer EscapeEventWriter)
EvictExpired removes observations older than maxAge and emits them as "stripped" escape events. Call this periodically (e.g., every maxAge/2).
func (*MangleCorrelator) PendingCount ¶
func (c *MangleCorrelator) PendingCount() int
PendingCount returns the number of unmatched Stage 1 observations (for monitoring).
func (*MangleCorrelator) RecordStage1 ¶
func (c *MangleCorrelator) RecordStage1(sessionID, sequenceType, hash string, byteLen int)
RecordStage1 records a Stage 1 observation for later correlation. It is assigned the next ordinal for this (sessionID, sequenceType) pair.
func (*MangleCorrelator) StartEviction ¶
func (c *MangleCorrelator) StartEviction(ctx context.Context, writer EscapeEventWriter)
StartEviction starts a background goroutine that calls EvictExpired periodically. Returns when ctx is cancelled.
type NoopEscapeEventWriter ¶
type NoopEscapeEventWriter struct{}
NoopEscapeEventWriter discards all events (used when capture_level=off).
func (NoopEscapeEventWriter) WriteEscapeEvent ¶
func (n NoopEscapeEventWriter) WriteEscapeEvent(_ context.Context, _ EscapeEventRecord)
type ParsedEscapeCode ¶
type ParsedEscapeCode struct {
RawBytes []byte // Original bytes
Category EscapeCategory // Type of sequence
Description string // Human-readable description
StartOffset int // Position in original data
EndOffset int // End position in original data
}
ParsedEscapeCode represents a single parsed escape sequence
type ParserStats ¶
ParserStats holds lifetime counters for a parser session.