logging

package
v0.8.0 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 logging provides a file-backed structured logger for the truestamp CLI: a single JSON-line log per invocation, written to a rotated file the user can grep later. The same logger is used by every subcommand (one-shot tools like verify, hash, download, upgrade and the long-lived console TUI) so a user reporting an issue has one place to look.

Default destination, by platform:

macOS:   ~/Library/Caches/truestamp/truestamp.log
Linux:   ~/.cache/truestamp/truestamp.log
Windows: %LOCALAPPDATA%\truestamp\Cache\truestamp.log

Files are rotated by size (10 MB default) with up to 5 compressed backups retained for 14 days. Output is one JSON object per line — directly grep/jq-able and easy to ingest into any log pipeline later.

All output passes through RedactingHandler before reaching the file: `api_key=…` and `Bearer …` substrings in attribute values, error chains, or message text are replaced with the REDACTED sentinel. This is a defense-in-depth safety net — call sites should still avoid putting secrets into log attributes in the first place.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultPath

func DefaultPath() string

DefaultPath returns the platform-default log file path so callers (typically Cobra flag registration) can show it in their help text. Returns the empty string on platforms where os.UserCacheDir fails; callers should treat that as "no default visible" and document the override path as the only way to relocate the log.

func Discard

func Discard() *slog.Logger

Discard returns a logger that drops every record. Used as a fallback when no file logger can be constructed (e.g. read-only home dir) so callers never have to worry about a nil logger.

func New

func New(opts Options) (*slog.Logger, string, error)

New returns a configured slog.Logger and the resolved log file path so the caller can surface it in diagnostic UIs. If file creation fails, a discard logger is returned along with the original error — callers should never crash over a logging failure.

The underlying file is opened lazily on the first write, so a command that emits no log records (e.g. `truestamp hash --silent` with --log-level error) pays no per-invocation file-creation cost.

Types

type Options

type Options struct {
	// Path overrides the default log file path. Empty = platform default.
	Path string

	// Level filters output. One of "debug", "info", "warn", "error";
	// empty defaults to "info".
	Level string

	// MaxSizeMB rotates after N megabytes. Defaults to 10.
	MaxSizeMB int

	// MaxBackups retains N rotated files. Defaults to 5.
	MaxBackups int

	// MaxAgeDays retains rotated files for N days. Defaults to 14.
	MaxAgeDays int

	// Component tags every record with a `component` attribute so log
	// readers can filter to a single subsystem (e.g. `component=console`
	// or `component=verify`). Empty string omits the attribute.
	Component string
}

Options configures logger construction.

type RedactingHandler

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

RedactingHandler wraps an underlying slog.Handler and runs every string attribute value, every error attribute, and the record's message through redact.String before forwarding the record. Group boundaries and attribute keys are passed through untouched — the redaction only targets values, where secrets can actually live.

func NewRedactingHandler

func NewRedactingHandler(inner slog.Handler) *RedactingHandler

NewRedactingHandler wraps inner so all records flowing through it have api_key / Bearer secrets replaced with the redact.REDACTED sentinel before they reach the underlying writer.

func (*RedactingHandler) Enabled

func (h *RedactingHandler) Enabled(ctx context.Context, level slog.Level) bool

Enabled delegates to the wrapped handler — redaction has no opinion on which levels are emitted.

func (*RedactingHandler) Handle

func (h *RedactingHandler) Handle(ctx context.Context, r slog.Record) error

Handle copies the record with a redacted message, walks every attribute redacting string and error values, then forwards to the inner handler. We rebuild the record (rather than mutating the original) because slog.Record values are designed to be value-copied safely.

func (*RedactingHandler) WithAttrs

func (h *RedactingHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new RedactingHandler whose inner handler has been pre-attributed with redacted versions of attrs. Pre-attribution is the path slog.Logger.With() takes, so this catches secrets that are baked into a child logger.

func (*RedactingHandler) WithGroup

func (h *RedactingHandler) WithGroup(name string) slog.Handler

WithGroup delegates — group names are caller-controlled identifiers, not values, and so don't need redaction.

Jump to

Keyboard shortcuts

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