Add Verbose log level between Info and Debug
Implemented full log level hierarchy: Fatal, Error, Warn, Info, Verbose, Debug. - Verbose level (-v) shows detailed operations like file changes (M/A/D) - Debug level (-vv) shows low-level tracing with caller info - Quiet mode (-q) sets level to Error, suppressing Info messages - Banner and summary output now use log levels for filtering
This commit is contained in:
@@ -13,16 +13,53 @@ import (
|
||||
"github.com/pterm/pterm"
|
||||
)
|
||||
|
||||
// Level is an alias for apex/log.Level for use by callers without importing apex/log.
|
||||
type Level = log.Level
|
||||
// Level represents log severity levels.
|
||||
// Lower values are more verbose.
|
||||
type Level int
|
||||
|
||||
const (
|
||||
// DebugLevel is for low-level tracing and structure inspection
|
||||
DebugLevel Level = iota
|
||||
// VerboseLevel is for detailed operational info (file listings, etc)
|
||||
VerboseLevel
|
||||
// InfoLevel is for operational summaries (default)
|
||||
InfoLevel
|
||||
// WarnLevel is for warnings
|
||||
WarnLevel
|
||||
// ErrorLevel is for errors
|
||||
ErrorLevel
|
||||
// FatalLevel is for fatal errors
|
||||
FatalLevel
|
||||
)
|
||||
|
||||
func (l Level) String() string {
|
||||
switch l {
|
||||
case DebugLevel:
|
||||
return "debug"
|
||||
case VerboseLevel:
|
||||
return "verbose"
|
||||
case InfoLevel:
|
||||
return "info"
|
||||
case WarnLevel:
|
||||
return "warn"
|
||||
case ErrorLevel:
|
||||
return "error"
|
||||
case FatalLevel:
|
||||
return "fatal"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// mu protects the output writers
|
||||
// mu protects the output writers and level
|
||||
mu sync.RWMutex
|
||||
// stdout is the writer for progress output
|
||||
stdout io.Writer = os.Stdout
|
||||
// stderr is the writer for log output
|
||||
stderr io.Writer = os.Stderr
|
||||
// currentLevel is our log level (includes Verbose)
|
||||
currentLevel Level = InfoLevel
|
||||
)
|
||||
|
||||
// SetOutput configures the output writers for the log package.
|
||||
@@ -67,31 +104,105 @@ func Init() {
|
||||
w := stderr
|
||||
mu.RUnlock()
|
||||
log.SetHandler(acli.New(w))
|
||||
log.SetLevel(log.InfoLevel)
|
||||
log.SetLevel(log.DebugLevel) // Let apex/log pass everything; we filter ourselves
|
||||
}
|
||||
|
||||
// isEnabled returns true if messages at the given level should be logged.
|
||||
func isEnabled(l Level) bool {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
return l >= currentLevel
|
||||
}
|
||||
|
||||
// Fatalf logs a formatted message at fatal level.
|
||||
func Fatalf(format string, args ...interface{}) {
|
||||
if isEnabled(FatalLevel) {
|
||||
log.Fatalf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Fatal logs a message at fatal level.
|
||||
func Fatal(arg string) {
|
||||
if isEnabled(FatalLevel) {
|
||||
log.Fatal(arg)
|
||||
}
|
||||
}
|
||||
|
||||
// Errorf logs a formatted message at error level.
|
||||
func Errorf(format string, args ...interface{}) {
|
||||
if isEnabled(ErrorLevel) {
|
||||
log.Errorf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Error logs a message at error level.
|
||||
func Error(arg string) {
|
||||
if isEnabled(ErrorLevel) {
|
||||
log.Error(arg)
|
||||
}
|
||||
}
|
||||
|
||||
// Warnf logs a formatted message at warn level.
|
||||
func Warnf(format string, args ...interface{}) {
|
||||
if isEnabled(WarnLevel) {
|
||||
log.Warnf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Warn logs a message at warn level.
|
||||
func Warn(arg string) {
|
||||
if isEnabled(WarnLevel) {
|
||||
log.Warn(arg)
|
||||
}
|
||||
}
|
||||
|
||||
// Infof logs a formatted message at info level.
|
||||
func Infof(format string, args ...interface{}) {
|
||||
log.Infof(format, args...)
|
||||
if isEnabled(InfoLevel) {
|
||||
log.Infof(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Info logs a message at info level.
|
||||
func Info(arg string) {
|
||||
log.Info(arg)
|
||||
if isEnabled(InfoLevel) {
|
||||
log.Info(arg)
|
||||
}
|
||||
}
|
||||
|
||||
// Verbosef logs a formatted message at verbose level.
|
||||
func Verbosef(format string, args ...interface{}) {
|
||||
if isEnabled(VerboseLevel) {
|
||||
log.Infof(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Verbose logs a message at verbose level.
|
||||
func Verbose(arg string) {
|
||||
if isEnabled(VerboseLevel) {
|
||||
log.Info(arg)
|
||||
}
|
||||
}
|
||||
|
||||
// Debugf logs a formatted message at debug level with caller location.
|
||||
func Debugf(format string, args ...interface{}) {
|
||||
DebugReal(fmt.Sprintf(format, args...), 2)
|
||||
if isEnabled(DebugLevel) {
|
||||
DebugReal(fmt.Sprintf(format, args...), 2)
|
||||
}
|
||||
}
|
||||
|
||||
// Debug logs a message at debug level with caller location.
|
||||
func Debug(arg string) {
|
||||
DebugReal(arg, 2)
|
||||
if isEnabled(DebugLevel) {
|
||||
DebugReal(arg, 2)
|
||||
}
|
||||
}
|
||||
|
||||
// DebugReal logs at debug level with caller info from the specified stack depth.
|
||||
func DebugReal(arg string, cs int) {
|
||||
if !isEnabled(DebugLevel) {
|
||||
return
|
||||
}
|
||||
_, callerFile, callerLine, ok := runtime.Caller(cs)
|
||||
if !ok {
|
||||
return
|
||||
@@ -102,25 +213,27 @@ func DebugReal(arg string, cs int) {
|
||||
|
||||
// Dump logs a spew dump of the arguments at debug level.
|
||||
func Dump(args ...interface{}) {
|
||||
DebugReal(spew.Sdump(args...), 2)
|
||||
if isEnabled(DebugLevel) {
|
||||
DebugReal(spew.Sdump(args...), 2)
|
||||
}
|
||||
}
|
||||
|
||||
// EnableDebugLogging sets the log level to debug.
|
||||
func EnableDebugLogging() {
|
||||
SetLevel(log.DebugLevel)
|
||||
SetLevel(DebugLevel)
|
||||
}
|
||||
|
||||
// VerbosityStepsToLogLevel converts a -v count to a log level.
|
||||
// 0 returns InfoLevel, 1+ returns DebugLevel.
|
||||
func VerbosityStepsToLogLevel(l int) log.Level {
|
||||
// 0 returns InfoLevel, 1 returns VerboseLevel, 2+ returns DebugLevel.
|
||||
func VerbosityStepsToLogLevel(l int) Level {
|
||||
switch l {
|
||||
case 0:
|
||||
return log.InfoLevel
|
||||
return InfoLevel
|
||||
case 1:
|
||||
return log.DebugLevel
|
||||
return VerboseLevel
|
||||
default:
|
||||
return DebugLevel
|
||||
}
|
||||
// -vv or more
|
||||
return log.DebugLevel
|
||||
}
|
||||
|
||||
// SetLevelFromVerbosity sets the log level based on -v flag count.
|
||||
@@ -129,26 +242,22 @@ func SetLevelFromVerbosity(l int) {
|
||||
}
|
||||
|
||||
// SetLevel sets the global log level.
|
||||
func SetLevel(arg log.Level) {
|
||||
log.SetLevel(arg)
|
||||
}
|
||||
|
||||
// GetLogger returns the underlying apex/log Logger.
|
||||
func GetLogger() *log.Logger {
|
||||
if logger, ok := log.Log.(*log.Logger); ok {
|
||||
return logger
|
||||
}
|
||||
panic("unable to get logger")
|
||||
func SetLevel(l Level) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
currentLevel = l
|
||||
}
|
||||
|
||||
// GetLevel returns the current log level.
|
||||
func GetLevel() log.Level {
|
||||
return GetLogger().Level
|
||||
func GetLevel() Level {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
return currentLevel
|
||||
}
|
||||
|
||||
// WithError returns a log entry with the error attached.
|
||||
func WithError(e error) *log.Entry {
|
||||
return GetLogger().WithError(e)
|
||||
return log.Log.WithError(e)
|
||||
}
|
||||
|
||||
// Progressf prints a progress message that overwrites the current line.
|
||||
|
||||
Reference in New Issue
Block a user