logtail

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package logtail reads the last N lines of a log file without loading the entire file into memory.

`cloop daemon` and `cloop agent` keep long-lived append-only logs; tailing them with os.ReadFile + strings.Split worked fine on day-one logs but reads the whole file every time. After a few weeks of uptime that grows to hundreds of MB, and `cloop daemon status` (which prints an 8-line tail) can then OOM the user's terminal session.

Tail seeks from the end of the file and reads at most DefaultMaxBytes, which is enough for at least the requested number of lines for any sane log line length.

Index

Constants

View Source
const DefaultMaxBytes = 1 << 20

DefaultMaxBytes caps how much of the file we will read from the end. 1 MiB comfortably covers thousands of typical log lines.

Variables

This section is empty.

Functions

func Follow

func Follow(ctx context.Context, path string, w io.Writer) error

Follow streams appended bytes from path to w, like `tail -f`. It tolerates:

  • The file not existing yet at start (waits with capped exponential backoff until it appears, instead of erroring out).
  • The file being removed mid-session (closes the fd, waits for the file to reappear, then resumes from the start of the new file).
  • The file being replaced (different inode) — reopens at offset 0.
  • The file being truncated (size shrinks below the current read offset) — reopens at offset 0.

Initial existing content is NOT replayed: the first open seeks to EOF. Callers wanting backlog should call Tail first, then Follow.

Follow returns nil when ctx is cancelled, or a non-nil error when an unrecoverable I/O failure occurs (e.g. permission denied reopening the file, or w returns an error). A vanished-then-reappeared file is not an error; backoff is capped so polling cannot busy-loop.

Follow is not internally concurrent and must be called from one goroutine.

func Tail

func Tail(path string, n int) ([]string, error)

Tail returns the last n lines of the file at path. It reads at most DefaultMaxBytes from the end of the file. If the file is smaller than that the whole file is read.

On a missing file Tail returns (nil, error wrapping fs.ErrNotExist) so callers can use errors.Is(err, fs.ErrNotExist) to render a friendly message. Empty files yield (nil, nil).

If n <= 0 the result is an empty slice.

func TailWithMax

func TailWithMax(path string, n int, maxBytes int64) ([]string, error)

TailWithMax is like Tail but lets the caller override the byte cap. Useful for tests and for callers that want a tighter bound.

Types

This section is empty.

Jump to

Keyboard shortcuts

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