refactor(ax): AX compliance pass — usage example comments on all exported functions

- Add usage example comments to Logger methods (SetLevel, Level, SetOutput, SetRedactKeys, Debug, Info, Warn, Error, Security)
- Add usage example comments to error introspection (Op, ErrCode, Root, AllOps, StackTrace, FormatStackTrace)
- Add usage example comments to package-level functions (Default, SetDefault)
- Banned imports (fmt, io, os, errors) are LEGITIMATE — this IS the logging/error abstraction layer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude 2026-03-29 21:11:16 +01:00 committed by Virgil
parent 4f7e730802
commit a543af9cc6
2 changed files with 34 additions and 0 deletions

View file

@ -128,6 +128,8 @@ func Join(errs ...error) error {
// Op extracts the operation name from an error.
// Returns empty string if the error is not an *Err.
//
// op := log.Op(err) // e.g. "user.Save"
func Op(err error) string {
var e *Err
if As(err, &e) {
@ -138,6 +140,8 @@ func Op(err error) string {
// ErrCode extracts the error code from an error.
// Returns empty string if the error is not an *Err or has no code.
//
// code := log.ErrCode(err) // e.g. "VALIDATION_FAILED"
func ErrCode(err error) string {
var e *Err
if As(err, &e) {
@ -161,6 +165,8 @@ func Message(err error) string {
// Root returns the root cause of an error chain.
// Unwraps until no more wrapped errors are found.
//
// cause := log.Root(err)
func Root(err error) error {
if err == nil {
return nil
@ -176,6 +182,8 @@ func Root(err error) error {
// AllOps returns an iterator over all operational contexts in the error chain.
// It traverses the error tree using errors.Unwrap.
//
// for op := range log.AllOps(err) { /* "api.Call" → "db.Query" → ... */ }
func AllOps(err error) iter.Seq[string] {
return func(yield func(string) bool) {
for err != nil {
@ -193,6 +201,8 @@ func AllOps(err error) iter.Seq[string] {
// StackTrace returns the logical stack trace (chain of operations) from an error.
// It returns an empty slice if no operational context is found.
//
// ops := log.StackTrace(err) // ["api.Call", "db.Query", "sql.Exec"]
func StackTrace(err error) []string {
var stack []string
for op := range AllOps(err) {
@ -202,6 +212,8 @@ func StackTrace(err error) []string {
}
// FormatStackTrace returns a pretty-printed logical stack trace.
//
// trace := log.FormatStackTrace(err) // "api.Call -> db.Query -> sql.Exec"
func FormatStackTrace(err error) string {
var ops []string
for op := range AllOps(err) {

22
log.go
View file

@ -169,6 +169,8 @@ func safeStyle(style func(string) string) func(string) string {
}
// SetLevel changes the log level.
//
// logger.SetLevel(log.LevelDebug)
func (l *Logger) SetLevel(level Level) {
l.mu.Lock()
l.level = normaliseLevel(level)
@ -176,6 +178,8 @@ func (l *Logger) SetLevel(level Level) {
}
// Level returns the current log level.
//
// current := logger.Level()
func (l *Logger) Level() Level {
l.mu.RLock()
defer l.mu.RUnlock()
@ -183,6 +187,8 @@ func (l *Logger) Level() Level {
}
// SetOutput changes the output writer.
//
// logger.SetOutput(os.Stdout)
func (l *Logger) SetOutput(w goio.Writer) {
if w == nil {
w = os.Stderr
@ -193,6 +199,8 @@ func (l *Logger) SetOutput(w goio.Writer) {
}
// SetRedactKeys sets the keys to be redacted.
//
// logger.SetRedactKeys("password", "token", "secret")
func (l *Logger) SetRedactKeys(keys ...string) {
l.mu.Lock()
l.redactKeys = slices.Clone(keys)
@ -282,6 +290,8 @@ func (l *Logger) log(level Level, prefix, msg string, keyvals ...any) {
}
// Debug logs a debug message with optional key-value pairs.
//
// logger.Debug("processing request", "method", "GET", "path", "/api/users")
func (l *Logger) Debug(msg string, keyvals ...any) {
if l.shouldLog(LevelDebug) {
l.mu.RLock()
@ -292,6 +302,8 @@ func (l *Logger) Debug(msg string, keyvals ...any) {
}
// Info logs an info message with optional key-value pairs.
//
// logger.Info("server started", "port", 8080)
func (l *Logger) Info(msg string, keyvals ...any) {
if l.shouldLog(LevelInfo) {
l.mu.RLock()
@ -302,6 +314,8 @@ func (l *Logger) Info(msg string, keyvals ...any) {
}
// Warn logs a warning message with optional key-value pairs.
//
// logger.Warn("high memory usage", "percent", 92)
func (l *Logger) Warn(msg string, keyvals ...any) {
if l.shouldLog(LevelWarn) {
l.mu.RLock()
@ -312,6 +326,8 @@ func (l *Logger) Warn(msg string, keyvals ...any) {
}
// Error logs an error message with optional key-value pairs.
//
// logger.Error("database connection failed", "err", err, "host", "db.local")
func (l *Logger) Error(msg string, keyvals ...any) {
if l.shouldLog(LevelError) {
l.mu.RLock()
@ -324,6 +340,8 @@ func (l *Logger) Error(msg string, keyvals ...any) {
// Security logs a security event with optional key-value pairs.
// It uses LevelError to ensure security events are visible even in restrictive
// log configurations.
//
// logger.Security("brute force detected", "ip", remoteAddr, "attempts", 50)
func (l *Logger) Security(msg string, keyvals ...any) {
if l.shouldLog(LevelError) {
l.mu.RLock()
@ -365,6 +383,8 @@ var defaultLogger = New(Options{Level: LevelInfo})
var defaultLoggerMu sync.RWMutex
// Default returns the default logger.
//
// logger := log.Default()
func Default() *Logger {
defaultLoggerMu.RLock()
defer defaultLoggerMu.RUnlock()
@ -372,6 +392,8 @@ func Default() *Logger {
}
// SetDefault sets the default logger.
//
// log.SetDefault(customLogger)
func SetDefault(l *Logger) {
if l == nil {
return