logger

package
v0.17.3 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2026 License: MIT Imports: 10 Imported by: 0

README

pkg/logger

Singleton file logger with automatic rotation, level filtering, and test isolation.

Files

File Role
logger.go Logger implementation, singleton management, all log methods

Key API

logger.Get()                          // Get singleton instance (auto-initializes)
logger.Get().Info("msg %s", arg)      // Log at INFO level
logger.Get().Error("failed: %v", err) // Log at ERROR level
logger.Get().ErrorPrint(...)          // Log to file AND print to stderr
logger.Get().SetLevel(logger.DEBUG)   // Change minimum log level
logger.Get().SetSession(ext, sess)    // Set "[ext=... sess=...]" prefix

Design Decisions

Singleton pattern. All packages share one logger instance so session context (external ID, session ID) is set once and appears in all log lines. The alternative — passing a logger to every function — would be significantly more invasive for minimal benefit.

Lumberjack for rotation. Uses gopkg.in/natefinch/lumberjack.v2 for automatic log rotation (1MB max size, 14 day retention, 20 backups, compressed). This is battle-tested and handles edge cases (rotation during write, permission issues) that a hand-rolled solution would miss.

ErrorPrint exists separately. Most errors are internal (sync failures, network issues) and only need to go to the log file. Some errors need user visibility (auth failures, setup issues). ErrorPrint writes to both the log file and stderr.

Test isolation. When testing.Testing() returns true, the logger auto-discards output unless CONFAB_LOG_DIR is explicitly set. This prevents tests from polluting the user's real log file at ~/.confab/logs/confab.log.

How to Extend

Adding a new log level: Add to the Level enum, add a method (e.g., Trace()), and handle it in log(). Consider whether existing levels are truly insufficient first.

Adding structured fields: The current logger uses printf-style formatting. If you need structured logging, consider whether the added complexity is justified — the log audience is primarily humans debugging issues.

Invariants

  • Thread-safe: all methods are mutex-protected.
  • Get() must always return a usable logger — if Init() fails, Get() falls back to a stderr-only logger.
  • ResetForTesting() is for tests only — it resets the singleton so the next Get() re-initializes.

Dependencies

Uses: gopkg.in/natefinch/lumberjack.v2, pkg/confabpath (default log dir under ~/.confab/logs)

Used by: nearly every package (via logger.Get())

Documentation

Index

Constants

View Source
const (
	// LogDirEnv is the environment variable to override the default log directory
	LogDirEnv = "CONFAB_LOG_DIR"
)

Variables

This section is empty.

Functions

func Close

func Close() error

Close closes the log file

func Debug

func Debug(format string, args ...interface{})

Debug logs a debug message (file only, not shown to user)

func Error

func Error(format string, args ...interface{})

Error logs an error (file only, not shown to user)

func ErrorPrint

func ErrorPrint(format string, args ...interface{})

ErrorPrint logs an error AND prints to stderr for user visibility

func Info

func Info(format string, args ...interface{})

Info logs an info message (file only, not shown to user)

func Init

func Init() error

Init initializes the logger (creates log directory and file).

Test isolation: When running under `go test` (detected via testing.Testing()), if CONFAB_LOG_DIR is not explicitly set, logs are discarded to avoid polluting the real log file. Tests that need to verify log output should set CONFAB_LOG_DIR to a temp directory.

func ResetForTesting

func ResetForTesting()

ResetForTesting resets the singleton state for tests. This allows tests to re-initialize the logger with different settings. Most tests don't need this - the auto-discard behavior handles isolation. Use this when testing logger initialization itself or verifying log output.

func SetSession

func SetSession(externalID, sessionID string)

SetSession sets session IDs that will be included in all log lines

func SetupForTesting added in v0.17.0

func SetupForTesting(t *testing.T) string

SetupForTesting wires the singleton logger to a fresh per-test temp directory so a test can observe what was actually emitted. Registers cleanup via t.Cleanup and returns the log directory; the canonical log file path is <dir>/confab.log.

Use this whenever a test needs to assert log content. For tests that just need silence, no setup is required — the auto-discard sink in Init() handles them.

func Warn

func Warn(format string, args ...interface{})

Warn logs a warning (file only, not shown to user)

Types

type Level

type Level int

Level represents the log level

const (
	DEBUG Level = iota
	INFO
	WARN
	ERROR
)

func (Level) String

func (l Level) String() string

type Logger

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

Logger manages logging to file and optionally stderr

func Get

func Get() *Logger

Get returns the logger instance (initializes if needed)

func (*Logger) Debug

func (l *Logger) Debug(format string, args ...interface{})

Debug logs a debug message

func (*Logger) Error

func (l *Logger) Error(format string, args ...interface{})

Error logs an error message

func (*Logger) ErrorPrint

func (l *Logger) ErrorPrint(format string, args ...interface{})

ErrorPrint logs an error to file AND prints to stderr for user visibility

func (*Logger) Info

func (l *Logger) Info(format string, args ...interface{})

Info logs an info message

func (*Logger) SetAlsoStderr

func (l *Logger) SetAlsoStderr(enabled bool)

SetAlsoStderr sets whether to also write to stderr

func (*Logger) SetLevel

func (l *Logger) SetLevel(level Level)

SetLevel sets the minimum log level

func (*Logger) SetSession

func (l *Logger) SetSession(externalID, sessionID string)

SetSession sets session IDs that will be included in all log lines. externalID is the Claude Code session ID, sessionID is the Confab backend session ID. Either can be empty if not yet known.

func (*Logger) Warn

func (l *Logger) Warn(format string, args ...interface{})

Warn logs a warning message

Jump to

Keyboard shortcuts

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