Help us shape the future of Go! Take the 2026 Go Developer Survey

logfile

package
v0.57.21 Latest Latest
Warning

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

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

Documentation

Overview

Package logfile provides file-based logging for bldr via logrus hooks.

Each log file destination is described by a spec string that can be passed via the --log-file CLI flag or the BLDR_LOG_FILE environment variable.

Spec Syntax

A spec string uses semicolon-separated key=value pairs:

level=DEBUG;format=json;path=.bldr/logs/{ts}.log

Keys:

  • level: logrus level threshold (default: DEBUG)
  • format: "text" or "json" (default: text)
  • path: file path, supports timestamp templates

A short form with just the path is also accepted:

.bldr/logs/{ts}.log

The special value "none" disables file logging (useful to override dev mode auto-enable via BLDR_LOG_FILE=none).

Timestamp Templates

Templates in the path are expanded once at process start:

  • {ts}: YYYYMMDD-HHMMSS (e.g., 20260222-143052)
  • {YYYY}: 4-digit year
  • {MM}: 2-digit month (zero-padded)
  • {DD}: 2-digit day (zero-padded)
  • {HH}: 2-digit hour (zero-padded, 24h)
  • {mm}: 2-digit minute (zero-padded)
  • {ss}: 2-digit second (zero-padded)

Dev Mode

In dev mode (--build-type dev), file logging is auto-enabled with the default spec "level=DEBUG;path=.bldr/logs/{ts}.log". Set BLDR_LOG_FILE=none or --log-file none to disable.

Index

Constants

View Source
const AutoDefaultEnvVar = "BLDR_LOG_FILE"

AutoDefaultEnvVar is the environment variable that controls the file logging spec. When set to a non-empty value, including "none", the user's configuration wins and BuildAutoDefaultSpec returns no spec.

View Source
const DefaultKeepLogs = 8

DefaultKeepLogs is the number of newest prior logs kept regardless of age. Each process start writes a new log, so frequent restarts would otherwise accumulate logs for the whole retention window.

View Source
const DefaultRetention = 7 * 24 * time.Hour

DefaultRetention is the on-disk retention duration applied when no project-scoped override resolves to a positive duration.

Variables

View Source
var ErrDisabled = errors.New("log file disabled")

ErrDisabled is returned by ParseLogFileSpec when the spec is "none".

Functions

func AttachLogFiles

func AttachLogFiles(logger *logrus.Logger, specs []LogFileSpec) (func(), error)

AttachLogFiles opens log files and attaches hooks to the logger. Returns a cleanup function that closes all hooks and files.

func BuildLogFileFlag

func BuildLogFileFlag(dest *cli.StringSlice) *cli.StringSliceFlag

BuildLogFileFlag returns a CLI flag for --log-file / --log-files.

func DiscardConsoleOutput added in v0.56.1

func DiscardConsoleOutput(logger *logrus.Logger)

DiscardConsoleOutput silences direct and level-filtered console sinks while leaving non-console hooks active.

func EnableAutoDefault added in v0.51.2

func EnableAutoDefault(
	logger *logrus.Logger,
	storageRoot string,
	retentionEnv string,
	now time.Time,
) (func(), error)

EnableAutoDefault enables file logging at the storage-root-relative default location when BLDR_LOG_FILE is unset. It prunes stale logs, attaches the file hook, and raises the logger level so console filtering applies via EnsureLoggerLevel.

Returns a cleanup function that closes the file hook (nil when no hook was attached). When BLDR_LOG_FILE is set or storageRoot is empty, this is a no-op and returns (nil, nil).

retentionEnv names the project-scoped retention env var (e.g. "SPACEWAVE_LOG_RETENTION_DAYS"); pass "" to skip the override and always use DefaultRetention. logger receives the retention warning (if any) before the hook is attached so it lands in stderr but not in the about-to-be-created file.

func EnsureLoggerLevel

func EnsureLoggerLevel(logger *logrus.Logger, specs []LogFileSpec)

EnsureLoggerLevel raises the logger level to the most verbose hook level. If the logger level is already sufficient, this is a no-op. Otherwise it redirects the logger's console output through a level-filtered hook so that --log-level controls console verbosity independently of file hooks.

func ExpandTemplate

func ExpandTemplate(path string, ts time.Time) string

ExpandTemplate expands timestamp templates in the given path string.

Supported templates:

  • {ts} -> YYYYMMDD-HHMMSS
  • {YYYY} -> 4-digit year
  • {MM} -> 2-digit month (zero-padded)
  • {DD} -> 2-digit day (zero-padded)
  • {HH} -> 2-digit hour (zero-padded, 24h)
  • {mm} -> 2-digit minute (zero-padded)
  • {ss} -> 2-digit second (zero-padded)

func PruneOldLogs added in v0.51.2

func PruneOldLogs(dir string, maxAge time.Duration, keep int, now time.Time) (int, error)

PruneOldLogs deletes regular .log files under dir whose mtime is older than maxAge relative to now, and all but the keep newest of the rest. A non-positive keep disables the count limit. Logs held open by a running writer (see AttachLogFiles) are never removed. Returns the number of files removed and the first error encountered (other failures are still attempted).

Non-existent dir is treated as success with zero removed files. Subdirectories and non-.log entries are skipped. Symlinks are not followed; their own metadata is consulted via os.Lstat semantics from os.ReadDir's DirEntry.

func ResolveLogLevel added in v0.51.2

func ResolveLogLevel(envChain []string, fallback logrus.Level) logrus.Level

ResolveLogLevel walks envChain in order, returning the first parseable logrus level found. Empty / unset values are skipped; a value that fails to parse is also skipped (callers receive fallback in that case). Returns fallback when no env var resolves.

func ResolveRetention added in v0.51.2

func ResolveRetention(env, raw string) (dur time.Duration, warn string)

ResolveRetention returns the configured on-disk log retention duration. It reads the project-scoped retention env var (e.g. SPACEWAVE_LOG_RETENTION_DAYS) and falls back to DefaultRetention when the variable is unset, blank, non-positive, or unparseable as a non-negative integer.

When the variable is set but cannot be parsed, the returned warn message is non-empty so callers can emit one logrus.Warn at startup. A successful parse always returns warn == "".

Types

type ConsoleHook

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

ConsoleHook is a logrus hook that writes synchronously to a writer with its own level threshold, independent of the Logger level.

func NewConsoleHook

func NewConsoleHook(w io.Writer, formatter logrus.Formatter, level logrus.Level) *ConsoleHook

NewConsoleHook creates a hook that writes synchronously to w.

func (*ConsoleHook) Fire

func (h *ConsoleHook) Fire(entry *logrus.Entry) error

Fire formats and writes the entry synchronously.

func (*ConsoleHook) Levels

func (h *ConsoleHook) Levels() []logrus.Level

Levels returns the log levels this hook is interested in.

type FileHook

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

FileHook is a logrus hook that writes log entries to a file.

func NewFileHook

func NewFileHook(w io.Writer, level logrus.Level, format string) *FileHook

NewFileHook creates a hook that writes to the given writer. Exported for testing with bytes.Buffer.

func (*FileHook) Close

func (h *FileHook) Close()

Close signals the writer goroutine to drain and stop, then waits for completion. If the writer implements io.Closer, it is closed. Close is idempotent.

func (*FileHook) Fire

func (h *FileHook) Fire(entry *logrus.Entry) error

Fire is called by logrus when a log entry is fired. It copies the entry to avoid races with logrus reusing the entry buffer. Entries fired after Close are dropped: the hook stays attached to the logger (logrus cannot detach a single hook) but nothing drains it.

func (*FileHook) Levels

func (h *FileHook) Levels() []logrus.Level

Levels returns the log levels this hook is interested in.

type LogFileSpec

type LogFileSpec struct {
	// Level is the logrus level threshold.
	Level logrus.Level
	// Format is the output format ("text" or "json").
	Format string
	// Path is the expanded file path (templates already resolved).
	Path string
}

LogFileSpec describes a log file destination.

func BuildAutoDefaultSpec added in v0.51.2

func BuildAutoDefaultSpec(storageRoot string, now time.Time) (LogFileSpec, bool)

BuildAutoDefaultSpec returns the auto-default LogFileSpec for an entrypoint that has no explicit BLDR_LOG_FILE configuration.

The resolved spec writes DEBUG-level text records to <storageRoot>/logs/{ts}.log, where {ts} is expanded against now. If BLDR_LOG_FILE is set to a non-empty value (including "none"), the user's configuration takes precedence and this function returns ok=false so the caller defers to the existing parsing path. Empty values behave like the variable is unset and still get the auto-default.

Callers receive the spec but are responsible for opening the file via AttachLogFiles and pruning old logs via PruneOldLogs.

func ParseLogFileSpec

func ParseLogFileSpec(spec string, ts time.Time) (LogFileSpec, error)

ParseLogFileSpec parses a log file spec string into a LogFileSpec.

Spec syntax (semicolon-delimited key=value pairs):

  • Full form: level=DEBUG;format=json;path=./.bldr/logs/{ts}.log
  • Short form: ./.bldr/logs/{ts}.log (path only, defaults apply)
  • "none" -> returns ErrDisabled

Default level: DEBUG. Default format: text. Unknown keys produce an error. Missing path produces an error.

func ParseLogFileSpecs

func ParseLogFileSpecs(raw []string, ts time.Time) ([]LogFileSpec, error)

ParseLogFileSpecs parses a list of raw spec strings into LogFileSpecs. Entries with value "none" are filtered out.

Jump to

Keyboard shortcuts

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