analytics

package
v1.48.0 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package analytics provides terminal escape code extraction and analysis

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DescribeSGR

func DescribeSGR(params string) string

DescribeSGR returns a human-readable description of SGR parameters

func DescribeSimpleEscape

func DescribeSimpleEscape(secondByte byte) string

DescribeSimpleEscape returns a description for a simple 2-byte escape

func GetDECPrivateModeDescription

func GetDECPrivateModeDescription(mode string) string

GetDECPrivateModeDescription returns a human-readable description for a DEC private mode

func GetEraseInDisplayDescription

func GetEraseInDisplayDescription(params string) string

Erase in Display descriptions

func GetEraseInLineDescription

func GetEraseInLineDescription(params string) string

Erase in Line descriptions

func GetOSCDescription

func GetOSCDescription(cmd string) string

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

func (s *EscapeCodeStore) Clear()

Clear removes all entries

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

type ParserStats struct {
	TotalSequences int64
	TotalMangled   int64
	Dropped        int64
}

ParserStats holds lifetime counters for a parser session.

type Stage

type Stage string

Stage identifies which pipeline stage observed a sequence.

const (
	StagePTYRead   Stage = "pty_read"
	StageTransport Stage = "transport"
	StageBrowser   Stage = "browser"
)

type Stage1Observation

type Stage1Observation struct {
	PayloadHash  string
	ByteLen      int
	WallTime     time.Time
	SessionID    string
	SequenceType string
}

Stage1Observation records a sequence seen at Stage 1 (PTY read) for later correlation with Stage 2.

Jump to

Keyboard shortcuts

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