dumps

package
v1.22.1 Latest Latest
Warning

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

Go to latest
Published: May 27, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package dumps receives, buffers, and fans out PHP `dump()`/`dd()` events captured by the lerd dump bridge (auto_prepend_file). The wire format is newline-delimited JSON. Production lerd-ui listens on a per-user Unix socket; tests bind TCP loopback. See docs/features/dumps.md.

Index

Constants

View Source
const DefaultAddr = "127.0.0.1:9913"

DefaultAddr is the loopback bind address the receiver listens on when callers ask for tcp. Picked to avoid clashing with Symfony's `var-dump-server` default (9912) so users who already run it for some other purpose don't see surprise interceptions.

View Source
const DefaultCapacity = 500

DefaultCapacity is the maximum number of events the ring keeps before it overwrites the oldest entry. Sized to match the web LogViewer's 500-line cap so the in-memory budget for either feed is similar.

View Source
const DefaultNetwork = "unix"

DefaultNetwork is the listen network used by lerd-ui. Unix sockets are the default because the FPM containers can already reach the host home directory via the %h:%h bind mount — using a TCP loopback listener would mean opening the receiver to the entire host network ring just so containers could route through host.containers.internal.

View Source
const KindDump = "dump"

KindDump is the only event kind PR1 emits. Reserved values like "query"/"job" will be added by future PRs without bumping ProtocolVersion.

View Source
const (
	// MaxLineBytes caps a single dump payload before bufio drops the line.
	// Sized to absorb VarCloner output for moderately large objects without
	// letting a runaway dump pin memory unboundedly.
	MaxLineBytes = 4 << 20 // 4 MiB

)
View Source
const ProtocolVersion = 1

ProtocolVersion is the wire-format version this package understands. Events with a different `v` are dropped.

Variables

This section is empty.

Functions

This section is empty.

Types

type Context

type Context struct {
	Type    string `json:"type"`
	Site    string `json:"site,omitempty"`
	Branch  string `json:"branch,omitempty"`
	Domain  string `json:"domain,omitempty"`
	Request string `json:"request,omitempty"`
	PID     int    `json:"pid,omitempty"`
}

Context describes where a dump came from. Type is "fpm" (web request) or "cli" (artisan, tinker, queue worker). Empty fields are omitted on the wire. Branch is non-empty only when the event originated inside a git worktree (set by the bridge from LERD_BRANCH, injected by nginx for worktree vhosts and by lerd's CLI helpers when shelling into a worktree path).

type Event

type Event struct {
	V     int             `json:"v"`
	ID    string          `json:"id"`
	TS    string          `json:"ts"`
	Kind  string          `json:"kind"`
	Ctx   Context         `json:"ctx"`
	Src   Source          `json:"src"`
	Label string          `json:"label,omitempty"`
	Text  string          `json:"text,omitempty"`
	Tree  json.RawMessage `json:"tree,omitempty"`
	Trunc bool            `json:"trunc,omitempty"`
}

Event is one dump payload. Tree is opaque JSON (the bridge sends a pre-walked tree from VarCloner in a future PR; PR1 ships only `text`).

func (Event) Valid

func (e Event) Valid() bool

Valid reports whether an event passes the minimum schema check applied by the listener before it is appended to the ring.

type FilterOpts

type FilterOpts struct {
	// Site exact-matches Ctx.Site when non-empty.
	Site string
	// Ctx exact-matches Ctx.Type ("fpm" or "cli") when non-empty.
	Ctx string
	// SinceID drops events whose ID is lexicographically <= SinceID.
	SinceID string
	// Limit caps the returned slice to the most recent N entries.
	// Zero or negative means no limit.
	Limit int
}

FilterOpts narrows a Snapshot. Zero-value fields are ignored.

type Hub

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

Hub fans Events out to subscribers. Publish is non-blocking; subscribers that don't drain fast enough drop events instead of stalling the listener.

func NewHub

func NewHub() *Hub

NewHub returns an empty Hub.

func (*Hub) Count

func (h *Hub) Count() int

Count returns the number of active subscribers (for status/diagnostics).

func (*Hub) Publish

func (h *Hub) Publish(e Event)

Publish delivers e to every active subscriber. Subscribers whose buffer is full miss the event; the publisher never blocks.

func (*Hub) Subscribe

func (h *Hub) Subscribe() (<-chan Event, func())

Subscribe returns a buffered channel that receives every subsequently published event, plus an unsubscribe func that closes the channel and removes it from the hub. The unsubscribe is idempotent.

type Ring

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

Ring is a fixed-size ring buffer of Events safe for concurrent use. Snapshots are taken under a read lock and returned in insertion order.

func NewRing

func NewRing(capacity int) *Ring

NewRing returns a ring with the given capacity. Non-positive capacity is replaced with DefaultCapacity.

func (*Ring) Append

func (r *Ring) Append(e Event)

Append stores e, evicting the oldest entry once the ring is full.

func (*Ring) Cap

func (r *Ring) Cap() int

Cap returns the maximum number of entries the ring can hold.

func (*Ring) Clear

func (r *Ring) Clear()

Clear empties the ring. Subsequent Snapshot() returns an empty slice.

func (*Ring) Filter

func (r *Ring) Filter(opts FilterOpts) []Event

Filter returns a Snapshot filtered by opts, preserving insertion order.

func (*Ring) Len

func (r *Ring) Len() int

Len returns the number of populated entries.

func (*Ring) Snapshot

func (r *Ring) Snapshot() []Event

Snapshot returns a copy of the ring contents in insertion order (oldest first). The returned slice is independent of the ring's backing array.

type Server

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

Server accepts loopback NDJSON connections from the PHP dump bridge, validates each line against ProtocolVersion, appends valid events to the ring, and publishes them to subscribers. Close once via Close().

func Listen

func Listen(ctx context.Context, addr string) (*Server, error)

Listen binds a TCP listener on addr and starts the accept loop. If addr is empty, DefaultAddr is used. The returned Server keeps running until Close is called or ctx is cancelled. Kept for tests and existing callers that already pass a TCP address; production lerd-ui uses ListenOn with "unix" so the receiver isn't reachable from the host network ring.

func ListenOn

func ListenOn(ctx context.Context, network, addr string) (*Server, error)

ListenOn binds on the given network and address. network is either "tcp" or "unix"; for "unix", any pre-existing socket at addr is removed first so a previous lerd-ui crash doesn't pin the path forever.

func (*Server) Addr

func (s *Server) Addr() string

Addr returns the bound address, useful when Listen was called with :0.

func (*Server) Clear

func (s *Server) Clear()

Clear empties the ring. Active subscribers continue to receive events.

func (*Server) Close

func (s *Server) Close() error

Close stops accepting connections, closes in-flight reads, and waits for outstanding goroutines to drain. Safe to call multiple times.

func (*Server) Filter

func (s *Server) Filter(opts FilterOpts) []Event

Filter returns a filtered Snapshot.

func (*Server) Len

func (s *Server) Len() int

Len returns the number of buffered events.

func (*Server) Push

func (s *Server) Push(e Event)

Push injects an event as if it had arrived on the wire. Used by tests to avoid juggling sockets when only ring/hub semantics matter.

func (*Server) Snapshot

func (s *Server) Snapshot() []Event

Snapshot returns a copy of the ring in insertion order.

func (*Server) Subscribe

func (s *Server) Subscribe() (<-chan Event, func())

Subscribe returns a buffered channel of new events plus an unsubscribe func.

func (*Server) Subscribers

func (s *Server) Subscribers() int

Subscribers returns the current subscriber count.

type Source

type Source struct {
	File string `json:"file"`
	Line int    `json:"line"`
}

Source identifies the file:line that produced a dump.

Jump to

Keyboard shortcuts

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