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:
parent
4f7e730802
commit
a543af9cc6
2 changed files with 34 additions and 0 deletions
12
errors.go
12
errors.go
|
|
@ -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
22
log.go
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue