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
parent 5eaea6ada4
commit 0c06f1498d
No known key found for this signature in database
GPG key ID: AF404715446AEB41
2 changed files with 34 additions and 0 deletions

View file

@ -129,6 +129,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) {
@ -139,6 +141,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) {
@ -162,6 +166,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
@ -177,6 +183,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 {
@ -194,6 +202,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) {
@ -203,6 +213,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

@ -134,6 +134,8 @@ func New(opts Options) *Logger {
func identity(s string) string { return s }
// SetLevel changes the log level.
//
// logger.SetLevel(log.LevelDebug)
func (l *Logger) SetLevel(level Level) {
l.mu.Lock()
l.level = level
@ -141,6 +143,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()
@ -148,6 +152,8 @@ func (l *Logger) Level() Level {
}
// SetOutput changes the output writer.
//
// logger.SetOutput(os.Stdout)
func (l *Logger) SetOutput(w goio.Writer) {
l.mu.Lock()
l.output = w
@ -155,6 +161,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)
@ -244,6 +252,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.log(LevelDebug, l.StyleDebug("[DBG]"), msg, keyvals...)
@ -251,6 +261,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.log(LevelInfo, l.StyleInfo("[INF]"), msg, keyvals...)
@ -258,6 +270,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.log(LevelWarn, l.StyleWarn("[WRN]"), msg, keyvals...)
@ -265,6 +279,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.log(LevelError, l.StyleError("[ERR]"), msg, keyvals...)
@ -274,6 +290,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.log(LevelError, l.StyleSecurity("[SEC]"), msg, keyvals...)
@ -298,11 +316,15 @@ func Username() string {
var defaultLogger = New(Options{Level: LevelInfo})
// Default returns the default logger.
//
// logger := log.Default()
func Default() *Logger {
return defaultLogger
}
// SetDefault sets the default logger.
//
// log.SetDefault(customLogger)
func SetDefault(l *Logger) {
defaultLogger = l
}