logbuf

package
v0.0.0-...-13c9b46 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package logbuf decides where log output goes while the watch display owns the terminal.

The watch command puts the terminal into raw mode on the alternate screen and draws a full frame several times a second. A log line written to standard error in the middle of that lands inside the frame: it is painted over by the next draw, so the user sees a flicker of text they cannot read and the warning is lost. Worse, a multi-line message with the line discipline off leaves the cursor somewhere the renderer does not expect and corrupts the frame until the next full redraw.

So while the terminal is held, the Writer this package hands the log handler does not touch the terminal at all. It appends to an in-memory buffer, and the buffer is flushed to standard error by ReleaseTerminal — which the terminal restore calls after the terminal has been put back, so the lines land on the user's shell where they can be read and scrolled. Everything else — every other command, and watch before it enters and after it leaves — writes straight through to standard error.

The buffer is capped

A watch at the most verbose log level can run for hours, and a buffer that grew for all of it would be a leak. Past the cap the first bytes are kept and later ones counted but dropped: the beginning of a failure is what explains it, and the flush ends with a single line saying how much it left out.

Pass goroutines log through this too, and the flush never waits on one

The writer is a zero-size value over process-wide state, so every goroutine writes through the same one — which matters because most of the warnings during a watch come from the worker side. The buffer mutex is therefore held across a copy and nothing else: never across a write to standard error, never across a system call. That is what lets ReleaseTerminal run on the way out without ever blocking on a pass goroutine — which may still be running and may still be logging. A line such a goroutine writes after the release goes straight to standard error, which by then is where it belongs.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HoldTerminal

func HoldTerminal()

HoldTerminal starts holding log output back, because the terminal is about to be taken over by the watch display. Idempotent, and safe to call from any goroutine.

func ReleaseTerminal

func ReleaseTerminal()

ReleaseTerminal stops holding log output back and writes what was held to standard error.

Call it after the terminal has been restored: the whole point is that these lines land on the shell rather than on the alternate screen.

Idempotent. A second call finds an empty buffer and writes nothing, which is what makes it safe on the several restore routes — the normal return, the panic path and the cleanup registry can all reach it, in any order.

Types

type Writer

type Writer struct{}

Writer is what the log handler is given: standard error, unless the terminal is held.

A zero-size value rather than a handle, because what it writes to is a process-wide fact — which terminal is in use — and not something a caller chooses per handler.

func (Writer) Write

func (Writer) Write(p []byte) (int, error)

Write implements io.Writer.

Jump to

Keyboard shortcuts

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