trace

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 11, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package trace provides execution tracing for containerized processes.

Platform Support

Linux: Uses the proc connector (netlink) for real-time exec notifications. Requires CAP_NET_ADMIN or root privileges.

macOS: Uses sysctl polling to detect new processes. This is a fallback since the Endpoint Security Framework (ESF) requires Apple entitlements. Polling interval is 100ms by default.

Other platforms: Uses a stub tracer that emits no events.

Usage

tracer, err := trace.New(trace.Config{PID: containerPID})
if err != nil {
    return err
}

tracer.OnExec(func(e trace.ExecEvent) {
    if e.IsGitCommit() {
        // Handle git commit
    }
})

if err := tracer.Start(); err != nil {
    return err
}
defer tracer.Stop()

Filtering

Set Config.PID to only trace a specific process and its children. Set Config.CgroupPath (Linux only) to trace all processes in a cgroup.

Package trace provides execution event types for capturing commands run in containers.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeEvent

func DecodeEvent(e Event) string

DecodeEvent decodes a single event.

func GetTraceEnv

func GetTraceEnv() map[string]string

GetTraceEnv extracts relevant environment variables for trace metadata.

func NewRecordingReader

func NewRecordingReader(r io.Reader, recorder *Recorder, eventType EventType) io.Reader

NewRecordingReader creates a reader that records to the trace.

func NewRecordingWriter

func NewRecordingWriter(w io.Writer, recorder *Recorder, eventType EventType) io.Writer

NewRecordingWriter creates a writer that records to the trace.

Types

type Config

type Config struct {
	CgroupPath string // Linux: cgroup path for the container
	PID        int    // Process ID to trace (and children)
}

Config configures the tracer.

type DecodedEvent

type DecodedEvent struct {
	Event
	Decoded string // human-readable representation
}

DecodedEvent represents a trace event with decoded control sequences.

type Event

type Event struct {
	TimestampNano int64     `json:"ts"`               // nanoseconds since trace start
	Type          EventType `json:"type"`             // "stdout", "stdin", "stderr", "resize", "signal"
	Data          []byte    `json:"data,omitempty"`   // raw bytes (base64 encoded in JSON)
	Size          *Size     `json:"size,omitempty"`   // for resize events
	Signal        string    `json:"signal,omitempty"` // for signal events (e.g., "SIGWINCH")
}

Event represents a single I/O or control event.

type EventType

type EventType string

EventType categorizes trace events.

const (
	EventStdout EventType = "stdout"
	EventStderr EventType = "stderr"
	EventStdin  EventType = "stdin"
	EventResize EventType = "resize"
	EventSignal EventType = "signal"
)

type ExecEvent

type ExecEvent struct {
	Timestamp  time.Time      `json:"timestamp"`
	PID        int            `json:"pid"`
	PPID       int            `json:"ppid"`
	Command    string         `json:"command"`
	Args       []string       `json:"args"`
	WorkingDir string         `json:"working_dir,omitempty"`
	ExitCode   *int           `json:"exit_code,omitempty"`
	Duration   *time.Duration `json:"duration,omitempty"`
}

ExecEvent represents a command execution captured by the tracer.

func (ExecEvent) IsBuildCommand

func (e ExecEvent) IsBuildCommand() bool

IsBuildCommand returns true if this event is a build command.

func (ExecEvent) IsGitCommit

func (e ExecEvent) IsGitCommit() bool

IsGitCommit returns true if this event is a git commit command.

type Metadata

type Metadata struct {
	Timestamp   time.Time         `json:"timestamp"`
	RunID       string            `json:"run_id"`
	Command     []string          `json:"command"`
	Environment map[string]string `json:"environment"` // TERM, LANG, COLUMNS, LINES, etc.
	InitialSize Size              `json:"initial_size"`
}

Metadata describes the environment and context of a trace.

type ProcConnectorTracer

type ProcConnectorTracer struct {
	// contains filtered or unexported fields
}

ProcConnectorTracer implements process tracing using Linux proc connector.

Privilege Requirements:

  • Requires CAP_NET_ADMIN capability OR root privileges
  • Without these, Start() will fail with "operation not permitted"
  • In containers, the host must allow CAP_NET_ADMIN (--cap-add=NET_ADMIN in Docker)

The proc connector provides real-time notifications of process events via netlink. This is more efficient than polling /proc and catches short-lived processes.

func NewProcConnectorTracer

func NewProcConnectorTracer(cfg Config) (*ProcConnectorTracer, error)

NewProcConnectorTracer creates a new proc connector tracer. The tracer is created in a stopped state; call Start() to begin receiving events. Start() requires CAP_NET_ADMIN capability or root privileges.

func (*ProcConnectorTracer) Events

func (t *ProcConnectorTracer) Events() <-chan ExecEvent

func (*ProcConnectorTracer) OnExec

func (t *ProcConnectorTracer) OnExec(cb func(ExecEvent))

func (*ProcConnectorTracer) Start

func (t *ProcConnectorTracer) Start() error

func (*ProcConnectorTracer) Stop

func (t *ProcConnectorTracer) Stop() error

type Recorder

type Recorder struct {
	// contains filtered or unexported fields
}

Recorder captures I/O events to a trace.

func NewRecorder

func NewRecorder(runID string, command []string, env map[string]string, initialSize Size) *Recorder

NewRecorder creates a new recorder with the given metadata.

func (*Recorder) AddEvent

func (r *Recorder) AddEvent(eventType EventType, data []byte)

AddEvent records an I/O event.

func (*Recorder) AddResize

func (r *Recorder) AddResize(width, height int)

AddResize records a terminal resize event.

func (*Recorder) AddSignal

func (r *Recorder) AddSignal(sig string)

AddSignal records a signal event.

func (*Recorder) Save

func (r *Recorder) Save(path string) error

Save writes the trace to a file.

type RecordingReader

type RecordingReader struct {
	// contains filtered or unexported fields
}

RecordingReader wraps an io.Reader and records all reads to the trace.

func (*RecordingReader) Read

func (rr *RecordingReader) Read(p []byte) (n int, err error)

type RecordingWriter

type RecordingWriter struct {
	// contains filtered or unexported fields
}

RecordingWriter wraps an io.Writer and records all writes to the trace.

func (*RecordingWriter) Write

func (rw *RecordingWriter) Write(p []byte) (n int, err error)

type Size

type Size struct {
	Width  int `json:"width"`
	Height int `json:"height"`
}

Size represents terminal dimensions.

type StubTracer

type StubTracer struct {
	// contains filtered or unexported fields
}

StubTracer is a no-op tracer for platforms without native tracing support.

func NewStubTracer

func NewStubTracer(cfg Config) *StubTracer

NewStubTracer creates a stub tracer that does nothing.

func (*StubTracer) Emit

func (t *StubTracer) Emit(event ExecEvent)

Emit allows manual event injection for testing.

func (*StubTracer) Events

func (t *StubTracer) Events() <-chan ExecEvent

func (*StubTracer) OnExec

func (t *StubTracer) OnExec(cb func(ExecEvent))

func (*StubTracer) Start

func (t *StubTracer) Start() error

func (*StubTracer) Stop

func (t *StubTracer) Stop() error

type Trace

type Trace struct {
	Metadata Metadata `json:"metadata"`
	Events   []Event  `json:"events"`
}

Trace captures terminal I/O with timing for replay and debugging.

func Load

func Load(path string) (*Trace, error)

Load reads a trace from a JSON file.

func (*Trace) Decode

func (t *Trace) Decode() []DecodedEvent

Decode returns a human-readable representation of trace events.

func (*Trace) FindClearScreen

func (t *Trace) FindClearScreen() []int

FindClearScreen returns events that clear the screen.

func (*Trace) FindResizeIssues

func (t *Trace) FindResizeIssues(windowNanos int64) []string

FindResizeIssues finds cases where screen is cleared shortly after resize. This can cause TUI rendering issues if the app clears before processing resize.

func (*Trace) Save

func (t *Trace) Save(path string) error

Save writes a trace to a JSON file.

type Tracer

type Tracer interface {
	// Start begins tracing.
	Start() error

	// Stop ends tracing.
	Stop() error

	// Events returns a channel of execution events.
	Events() <-chan ExecEvent

	// OnExec registers a callback for execution events.
	OnExec(func(ExecEvent))
}

Tracer captures command executions inside a container.

func New

func New(cfg Config) (Tracer, error)

New creates a platform-appropriate tracer. On Linux, uses proc connector for real-time notifications. On macOS, uses sysctl polling. On other platforms, returns a stub tracer.

Jump to

Keyboard shortcuts

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