// Level parsing and filter primitives. The Level values themselves live in
// lambdalog.go; this file provides the conversion layer that reads levels
// from config files, environment variables, and HTTP query parameters.
package lambdalog
import (
"fmt"
"strings"
)
// ParseLevel accepts any of the canonical level names (case-insensitive),
// single-letter shorthand (d/i/w/e), and numeric severities matching
// syslog-style values (7, 6, 4, 3). Unknown inputs yield an error; callers
// typically treat that as "keep the current level".
func ParseLevel(s string) (Level, error) {
switch strings.ToLower(strings.TrimSpace(s)) {
case "debug", "d", "7":
return LevelDebug, nil
case "info", "i", "6":
return LevelInfo, nil
case "warn", "warning", "w", "4":
return LevelWarn, nil
case "error", "err", "e", "3":
return LevelError, nil
case "":
return LevelInfo, fmt.Errorf("empty level string")
default:
return LevelInfo, fmt.Errorf("unknown level %q", s)
}
}
// MustParseLevel is the panicking sibling of ParseLevel, intended for use at
// package init time where an invalid configuration is unrecoverable.
func MustParseLevel(s string) Level {
lv, err := ParseLevel(s)
if err != nil {
panic(err)
}
return lv
}
// String returns the canonical lower-case name for a Level. Unknown levels
// render as "info" to match the default rank behaviour.
func (l Level) String() string {
switch l {
case LevelDebug:
return "debug"
case LevelInfo:
return "info"
case LevelWarn:
return "warn"
case LevelError:
return "error"
default:
return "info"
}
}
// Enabled reports whether records at lv would be emitted by a logger with
// threshold min. Exposed for external callers that want to avoid building
// expensive attribute slices when the level is filtered out.
func Enabled(lv, min Level) bool {
return levelEnabled(lv, min)
}
// Levels returns the four recognised levels in ascending severity order.
// Useful for callers wiring up CLI flag completers or config validators.
func Levels() []Level {
return []Level{LevelDebug, LevelInfo, LevelWarn, LevelError}
}
// LevelFilter is a composable predicate: it returns true when a record at
// lv should be emitted. Filters stack via All/Any combinators and plug into
// Logger through WithFilter.
type LevelFilter func(Level) bool
// AllLevels accepts every level.
func AllLevels() LevelFilter { return func(Level) bool { return true } }
// AtLeast returns a filter that admits records whose level is at or above
// the given threshold.
func AtLeast(min Level) LevelFilter {
return func(lv Level) bool { return levelEnabled(lv, min) }
}
// Only returns a filter that admits records at exactly one level.
func Only(lv Level) LevelFilter {
return func(other Level) bool { return other == lv }
}