Documentation
¶
Overview ¶
Package logging sets up ogcode's process-wide slog logger: a size-rotated, owner-only log file that receives everything at the configured level, and a terminal that sees only what the user must act on (errors, by default).
Configuration is by environment, like the rest of ogcode's runtime knobs:
OGCODE_LOG_LEVEL debug | info (default) | warn | error — the file's threshold OGCODE_LOG_FORMAT text (default) | json — the file's format OGCODE_LOG_CONSOLE off | error (default) | warn | info | debug — the terminal's threshold OGCODE_LOG_DIR root for log files (default ~/.ogcode/logs; each project gets a folder inside) OGCODE_LOG_MAX_SIZE_MB rotate the file past this size (default 10) OGCODE_LOG_MAX_FILES rotated files kept (default 5) OGCODE_LOG_MAX_AGE_DAYS rotated files older than this are deleted (default 14, 0 = keep) OGCODE_LOG_COMPRESS gzip rotated files (default on)
Records can also be shipped to PostHog Logs, off by default:
OGCODE_POSTHOG_LOGS on | off (default) — ship records to PostHog Logs OGCODE_POSTHOG_LOGS_LEVEL severity floor for shipped records (default warn)
Shipping is opt-in and honours DO_NOT_TRACK; records are redacted before they leave the process.
Index ¶
Constants ¶
const ( DefaultMaxSizeMB = 10 DefaultMaxFiles = 5 DefaultMaxAgeDays = 14 )
Defaults for a log file's size and retention. The worst case on disk is MaxSizeMB × (MaxFiles + 1), before compression.
const DefaultRemoteLevel = slog.LevelWarn
DefaultRemoteLevel is the floor below which records are never shipped to PostHog: a debug log file is for the machine it runs on, and shipping debug lines would be both noisy and a surprise. The file's level raises or lowers nothing here — OGCODE_POSTHOG_LOGS_LEVEL is the only remote knob.
const LevelOff = slog.Level(math.MaxInt32)
LevelOff is a threshold no record reaches: the sink is silent.
const Redacted = "[REDACTED]"
Redacted replaces a secret in a log line.
Variables ¶
This section is empty.
Functions ¶
func ProjectDir ¶
ProjectDir is the log directory for the project at dir: one folder per project under root, so projects running side by side never share a file. The folder is named after the project, for a person looking for it, with a short hash of its path appended, so two checkouts that are both called "app" stay apart. The path is canonicalized the way portmap keys a project (absolute, symlinks resolved, cleaned), so one project has one log folder however its path was spelled.
Types ¶
type Logger ¶
type Logger struct {
*slog.Logger
// ConsoleFallback reports that the log file could not be opened and the
// terminal is carrying its records. Set once by New.
ConsoleFallback bool
// contains filtered or unexported fields
}
Logger is a configured process logger and the file behind it.
func New ¶
New builds a logger from o. It never fails: if the file cannot be opened (read-only disk, no permission) the terminal takes over at the file's level, and says why, so nothing is lost silently.
func Setup ¶
Setup builds a logger from o and installs it as the process default, which also routes the standard library's log package (net/http's server errors, for one) through it.
func (*Logger) Close ¶
Close stops the PostHog sink (flushing any buffered records), closes the file and waits for pending rotation housekeeping.
func (*Logger) Started ¶
Started logs the line that opens a process's section of the log: which process, in which directory, which version, under which settings. It makes a file shared by restarts (and, rarely, by concurrent processes) readable, and names the project a per-project log folder belongs to.
type Options ¶
type Options struct {
// Dir and Name place the log file. Empty Name means no file: the terminal
// is the only sink (used by commands like `version` that do no work worth
// keeping and must not create .ogcode/ wherever they are run).
Dir string
Name string
Level slog.Level // file threshold
Format string // "text" or "json"; the file's format
Console slog.Level // terminal threshold; LevelOff silences it
Rotate RotateOptions
// Stderr is the terminal sink. Nil means os.Stderr.
Stderr io.Writer
}
Options configure the process logger.
type RotateOptions ¶
type RotateOptions struct {
// MaxSize is the size in bytes at which the active file is rotated.
MaxSize int64
// MaxBackups is how many rotated files are kept; 0 keeps them all.
MaxBackups int
// MaxAge removes rotated files older than this; 0 keeps them regardless.
MaxAge time.Duration
// Compress gzips rotated files.
Compress bool
}
RotateOptions bound how much disk a log file may take.
type RotatingFile ¶
type RotatingFile struct {
// contains filtered or unexported fields
}
RotatingFile is an io.Writer that appends to a log file and, when the file would grow past MaxSize, renames it to <stem>-<UTC stamp><ext> and starts a fresh one. Pruning and compressing the rotated files happens off the write path, in one background goroutine.
Files are created 0600 and a directory it creates 0700: log lines carry paths, prompts and provider errors, which are the user's alone to read.
Several processes may append to the same file (two servers or two `ogcode run` in one project). Appends are O_APPEND, so records never interleave mid-line; each writer re-checks the path every followInterval, so after one process rotates, the others follow it to the new file within a second rather than writing on into the backup — and the size each one rotates on includes the others' writes.
func OpenRotating ¶
func OpenRotating(path string, opts RotateOptions) (*RotatingFile, error)
OpenRotating opens (creating if needed) the log file at path.
func (*RotatingFile) Close ¶
func (r *RotatingFile) Close() error
Close closes the file and waits for any pruning or compression in flight.