First commit of golang CLI.
This commit is contained in:
185
wild-cli/internal/output/logger.go
Normal file
185
wild-cli/internal/output/logger.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package output
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
// Global state for output formatting
|
||||
colorEnabled = true
|
||||
verboseMode = false
|
||||
|
||||
// Colors
|
||||
colorInfo = color.New(color.FgBlue)
|
||||
colorSuccess = color.New(color.FgGreen)
|
||||
colorWarning = color.New(color.FgYellow)
|
||||
colorError = color.New(color.FgRed)
|
||||
colorHeader = color.New(color.FgBlue, color.Bold)
|
||||
)
|
||||
|
||||
// Logger provides structured logging with colored output
|
||||
type Logger struct {
|
||||
zap *zap.Logger
|
||||
}
|
||||
|
||||
// NewLogger creates a new logger instance
|
||||
func NewLogger() *Logger {
|
||||
config := zap.NewDevelopmentConfig()
|
||||
config.DisableStacktrace = true
|
||||
config.Level = zap.NewAtomicLevelAt(zap.InfoLevel)
|
||||
|
||||
if verboseMode {
|
||||
config.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
|
||||
}
|
||||
|
||||
logger, _ := config.Build()
|
||||
|
||||
return &Logger{
|
||||
zap: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// Sync flushes any buffered log entries
|
||||
func (l *Logger) Sync() error {
|
||||
return l.zap.Sync()
|
||||
}
|
||||
|
||||
// Info logs an info message
|
||||
func (l *Logger) Info(msg string, keysAndValues ...interface{}) {
|
||||
l.zap.Sugar().Infow(msg, keysAndValues...)
|
||||
|
||||
// Also print to stdout with formatting
|
||||
if colorEnabled {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "%s %s\n", colorInfo.Sprint("INFO:"), msg)
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "INFO: %s\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Success logs a success message
|
||||
func (l *Logger) Success(msg string, keysAndValues ...interface{}) {
|
||||
l.zap.Sugar().Infow(msg, keysAndValues...)
|
||||
|
||||
if colorEnabled {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "%s %s\n", colorSuccess.Sprint("SUCCESS:"), msg)
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "SUCCESS: %s\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Warning logs a warning message
|
||||
func (l *Logger) Warning(msg string, keysAndValues ...interface{}) {
|
||||
l.zap.Sugar().Warnw(msg, keysAndValues...)
|
||||
|
||||
if colorEnabled {
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", colorWarning.Sprint("WARNING:"), msg)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "WARNING: %s\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Error logs an error message
|
||||
func (l *Logger) Error(msg string, keysAndValues ...interface{}) {
|
||||
l.zap.Sugar().Errorw(msg, keysAndValues...)
|
||||
|
||||
if colorEnabled {
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", colorError.Sprint("ERROR:"), msg)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "ERROR: %s\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Debug logs a debug message (only shown in verbose mode)
|
||||
func (l *Logger) Debug(msg string, keysAndValues ...interface{}) {
|
||||
l.zap.Sugar().Debugw(msg, keysAndValues...)
|
||||
|
||||
if verboseMode {
|
||||
if colorEnabled {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "%s %s\n", color.New(color.FgMagenta).Sprint("DEBUG:"), msg)
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "DEBUG: %s\n", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Header prints a formatted header
|
||||
func (l *Logger) Header(msg string) {
|
||||
if colorEnabled {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "\n%s\n\n", colorHeader.Sprintf("=== %s ===", msg))
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "\n=== %s ===\n\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Printf provides formatted output
|
||||
func (l *Logger) Printf(format string, args ...interface{}) {
|
||||
fmt.Printf(format, args...)
|
||||
}
|
||||
|
||||
// Print provides simple output
|
||||
func (l *Logger) Print(msg string) {
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
// Global functions for package-level access
|
||||
|
||||
// DisableColor disables colored output
|
||||
func DisableColor() {
|
||||
colorEnabled = false
|
||||
color.NoColor = true
|
||||
}
|
||||
|
||||
// SetVerbose enables or disables verbose mode
|
||||
func SetVerbose(enabled bool) {
|
||||
verboseMode = enabled
|
||||
}
|
||||
|
||||
// Package-level convenience functions
|
||||
func Info(msg string) {
|
||||
if colorEnabled {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "%s %s\n", colorInfo.Sprint("INFO:"), msg)
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "INFO: %s\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func Success(msg string) {
|
||||
if colorEnabled {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "%s %s\n", colorSuccess.Sprint("SUCCESS:"), msg)
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "SUCCESS: %s\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func Warning(msg string) {
|
||||
if colorEnabled {
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", colorWarning.Sprint("WARNING:"), msg)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "WARNING: %s\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func Error(msg string) {
|
||||
if colorEnabled {
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", colorError.Sprint("ERROR:"), msg)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "ERROR: %s\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func Header(msg string) {
|
||||
if colorEnabled {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "\n%s\n\n", colorHeader.Sprintf("=== %s ===", msg))
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "\n=== %s ===\n\n", msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Printf provides formatted output (package-level function)
|
||||
func Printf(format string, args ...interface{}) {
|
||||
fmt.Printf(format, args...)
|
||||
}
|
Reference in New Issue
Block a user