logging

package
v1.5.3 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package logging provides log interception functionality for the TUI.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Interceptor

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

Interceptor wraps an slog.Handler to intercept log messages and send them to the TUI. It also optionally writes logs to a file in verbose mode.

Concurrency model: the slog Handle path is hot — engine goroutines call it from many places. tea.Program.Send blocks until the message lands in BT's input channel; if the TUI's Update loop is busy, that blocks the calling goroutine. With debug logging on, the engine emits hundreds of log lines per second, and any backpressure from the TUI rapidly turns into a deadlock (engine goroutine stuck on Send → TUI has nothing new to render → engine never makes progress).

To break that, the interceptor decouples Handle from Send via a buffered channel + worker goroutine. Handle pushes the Msg non-blocking (drops on full); the worker drains and calls Send.

func NewInterceptor

func NewInterceptor(
	originalHandler slog.Handler, program *tea.Program, logFilePath string, suppressStderr bool,
) (*Interceptor, error)

NewInterceptor creates a log interceptor that sends logs to the TUI. If logFilePath is not empty, logs will also be written to that file. If suppressStderr is true, logs won't be sent to the original handler (useful for TUI mode).

func Setup

func Setup(logger *slog.Logger, program *tea.Program, logFilePath string, suppressStderr bool) (*Interceptor, error)

Setup configures the provided logger to intercept logs and send them to the TUI. If logFilePath is not empty, logs will also be written to that file. If suppressStderr is true, logs won't be sent to stderr (useful for TUI mode). Returns the interceptor (to be closed when done) and an error if setup fails.

func (*Interceptor) Close

func (l *Interceptor) Close() error

Close stops the worker goroutine, flushes pending file writes, and closes the log file. Safe to call multiple times.

func (*Interceptor) Enabled

func (l *Interceptor) Enabled(ctx context.Context, level slog.Level) bool

Enabled reports whether the handler handles records at the given level.

func (*Interceptor) FlushBuffer

func (l *Interceptor) FlushBuffer()

FlushBuffer writes all buffered logs to the original handler (stderr). Call this after the TUI exits to show any logs that occurred during execution.

func (*Interceptor) Handle

func (l *Interceptor) Handle(ctx context.Context, record slog.Record) error

Handle processes a log record by sending it to the TUI and optionally writing to file.

func (*Interceptor) WithAttrs

func (l *Interceptor) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new handler with additional attributes.

Subloggers share the parent's program/file/worker so attributed logs route through the same backpressure path.

func (*Interceptor) WithGroup

func (l *Interceptor) WithGroup(name string) slog.Handler

WithGroup returns a new handler with an additional group.

type Msg

type Msg struct {
	Timestamp time.Time
	Level     string
	Message   string
}

Msg is a bubbletea message sent when a log entry is intercepted.

Jump to

Keyboard shortcuts

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