Compare commits
	
		
			3 Commits
		
	
	
		
			v1.1.1
			...
			d9564c2b98
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d9564c2b98 | |||
| 04f9b0db6e | |||
| 93557356e9 | 
							
								
								
									
										106
									
								
								colors.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								colors.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"math/rand/v2"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// Reset
 | 
				
			||||||
 | 
						Reset = "\033[0m" // Text Reset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Regular Colors
 | 
				
			||||||
 | 
						Black  = "\033[0;30m" // Black
 | 
				
			||||||
 | 
						Red    = "\033[0;31m" // Red
 | 
				
			||||||
 | 
						Green  = "\033[0;32m" // Green
 | 
				
			||||||
 | 
						Yellow = "\033[0;33m" // Yellow
 | 
				
			||||||
 | 
						Blue   = "\033[0;34m" // Blue
 | 
				
			||||||
 | 
						Purple = "\033[0;35m" // Purple
 | 
				
			||||||
 | 
						Cyan   = "\033[0;36m" // Cyan
 | 
				
			||||||
 | 
						White  = "\033[0;37m" // White
 | 
				
			||||||
 | 
						Orange = "\033[38;5;208m" // Orange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Bold
 | 
				
			||||||
 | 
						BBlack  = "\033[1;30m" // Black
 | 
				
			||||||
 | 
						BRed    = "\033[1;31m" // Red
 | 
				
			||||||
 | 
						BGreen  = "\033[1;32m" // Green
 | 
				
			||||||
 | 
						BYellow = "\033[1;33m" // Yellow
 | 
				
			||||||
 | 
						BBlue   = "\033[1;34m" // Blue
 | 
				
			||||||
 | 
						BPurple = "\033[1;35m" // Purple
 | 
				
			||||||
 | 
						BCyan   = "\033[1;36m" // Cyan
 | 
				
			||||||
 | 
						BWhite  = "\033[1;37m" // White
 | 
				
			||||||
 | 
						BOrange = "\033[1;38;5;208m" // Bold Orange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Underline
 | 
				
			||||||
 | 
						UBlack  = "\033[4;30m" // Black
 | 
				
			||||||
 | 
						URed    = "\033[4;31m" // Red
 | 
				
			||||||
 | 
						UGreen  = "\033[4;32m" // Green
 | 
				
			||||||
 | 
						UYellow = "\033[4;33m" // Yellow
 | 
				
			||||||
 | 
						UBlue   = "\033[4;34m" // Blue
 | 
				
			||||||
 | 
						UPurple = "\033[4;35m" // Purple
 | 
				
			||||||
 | 
						UCyan   = "\033[4;36m" // Cyan
 | 
				
			||||||
 | 
						UWhite  = "\033[4;37m" // White
 | 
				
			||||||
 | 
						UOrange = "\033[4;38;5;208m" // Underline Orange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Background
 | 
				
			||||||
 | 
						On_Black  = "\033[40m" // Black
 | 
				
			||||||
 | 
						On_Red    = "\033[41m" // Red
 | 
				
			||||||
 | 
						On_Green  = "\033[42m" // Green
 | 
				
			||||||
 | 
						On_Yellow = "\033[43m" // Yellow
 | 
				
			||||||
 | 
						On_Blue   = "\033[44m" // Blue
 | 
				
			||||||
 | 
						On_Purple = "\033[45m" // Purple
 | 
				
			||||||
 | 
						On_Cyan   = "\033[46m" // Cyan
 | 
				
			||||||
 | 
						On_White  = "\033[47m" // White
 | 
				
			||||||
 | 
						On_Orange = "\033[48;5;208m" // Orange Background
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// High Intensty
 | 
				
			||||||
 | 
						IBlack  = "\033[0;90m" // Black
 | 
				
			||||||
 | 
						IRed    = "\033[0;91m" // Red
 | 
				
			||||||
 | 
						IGreen  = "\033[0;92m" // Green
 | 
				
			||||||
 | 
						IYellow = "\033[0;93m" // Yellow
 | 
				
			||||||
 | 
						IBlue   = "\033[0;94m" // Blue
 | 
				
			||||||
 | 
						IPurple = "\033[0;95m" // Purple
 | 
				
			||||||
 | 
						ICyan   = "\033[0;96m" // Cyan
 | 
				
			||||||
 | 
						IWhite  = "\033[0;97m" // White
 | 
				
			||||||
 | 
						IOrange = "\033[0;38;5;208m" // Intense Orange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Bold High Intensty
 | 
				
			||||||
 | 
						BIBlack  = "\033[1;90m" // Black
 | 
				
			||||||
 | 
						BIRed    = "\033[1;91m" // Red
 | 
				
			||||||
 | 
						BIGreen  = "\033[1;92m" // Green
 | 
				
			||||||
 | 
						BIYellow = "\033[1;93m" // Yellow
 | 
				
			||||||
 | 
						BIBlue   = "\033[1;94m" // Blue
 | 
				
			||||||
 | 
						BIPurple = "\033[1;95m" // Purple
 | 
				
			||||||
 | 
						BICyan   = "\033[1;96m" // Cyan
 | 
				
			||||||
 | 
						BIWhite  = "\033[1;97m" // White
 | 
				
			||||||
 | 
						BIOrange = "\033[1;38;5;208m" // Bold Intense Orange
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// High Intensty backgrounds
 | 
				
			||||||
 | 
						On_IBlack  = "\033[0;100m" // Black
 | 
				
			||||||
 | 
						On_IRed    = "\033[0;101m" // Red
 | 
				
			||||||
 | 
						On_IGreen  = "\033[0;102m" // Green
 | 
				
			||||||
 | 
						On_IYellow = "\033[0;103m" // Yellow
 | 
				
			||||||
 | 
						On_IBlue   = "\033[0;104m" // Blue
 | 
				
			||||||
 | 
						On_IPurple = "\033[10;95m" // Purple
 | 
				
			||||||
 | 
						On_ICyan   = "\033[0;106m" // Cyan
 | 
				
			||||||
 | 
						On_IWhite  = "\033[0;107m" // White
 | 
				
			||||||
 | 
						On_IOrange = "\033[0;48;5;208m" // Intense Orange Background
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The acceptable range is [16, 231] but here we remove some very dark colors
 | 
				
			||||||
 | 
					// That make text unreadable on a dark terminal
 | 
				
			||||||
 | 
					// See https://www.hackitu.de/termcolor256/
 | 
				
			||||||
 | 
					var colors = []int{22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 57, 62, 63, 64, 65, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 148, 149, 150, 151, 152, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 184, 185, 186, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 226, 227, 228, 229, 230}
 | 
				
			||||||
 | 
					var colorsIndex int = -1
 | 
				
			||||||
 | 
					var shuffled bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GenerateRandomAnsiColor() string {
 | 
				
			||||||
 | 
						if !shuffled {
 | 
				
			||||||
 | 
							rand.Shuffle(len(colors), func(i int, j int) {
 | 
				
			||||||
 | 
								colors[i], colors[j] = colors[j], colors[i]
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							shuffled = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						colorsIndex++
 | 
				
			||||||
 | 
						return fmt.Sprintf("\033[1;4;38;5;%dm", colors[colorsIndex%len(colors)])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										230
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										230
									
								
								main.go
									
									
									
									
									
								
							@@ -1,4 +1,5 @@
 | 
				
			|||||||
package cylogger
 | 
					// package cylogger
 | 
				
			||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
@@ -38,38 +39,53 @@ const (
 | 
				
			|||||||
	LevelPrefix
 | 
						LevelPrefix
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var levelNames = map[LogLevel]string{
 | 
					// LevelStyle defines the visual style for a log level
 | 
				
			||||||
	LevelError:   "ERROR",
 | 
					type LevelStyle struct {
 | 
				
			||||||
	LevelWarning: "WARNING",
 | 
						Tag                    string // e.g., "ERROR", "INFO"
 | 
				
			||||||
	LevelInfo:    "INFO",
 | 
						TagColor               string // ANSI code for tag text
 | 
				
			||||||
	LevelDebug:   "DEBUG",
 | 
						TagBackgroundColor     string // ANSI code for tag background
 | 
				
			||||||
	LevelTrace:   "TRACE",
 | 
						MessageColor           string // ANSI code for message text
 | 
				
			||||||
	LevelLua:     "LUA",
 | 
						MessageBackgroundColor string // ANSI code for message background
 | 
				
			||||||
	LevelPrefix:  "PREFIX",
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var levelColors = map[LogLevel]string{
 | 
					// levelStyles maps LogLevel to its display style
 | 
				
			||||||
	LevelError:   "\033[1;31m", // Bold Red
 | 
					var levelStyles = map[LogLevel]LevelStyle{
 | 
				
			||||||
	LevelWarning: "\033[1;33m", // Bold Yellow
 | 
						LevelError: {
 | 
				
			||||||
	LevelInfo:    "\033[1;32m", // Bold Green
 | 
							Tag:                    "ERROR",
 | 
				
			||||||
	LevelDebug:   "\033[1;36m", // Bold Cyan
 | 
							TagColor:               BIRed,    // Bold Intense Red
 | 
				
			||||||
	LevelTrace:   "\033[1;35m", // Bold Magenta
 | 
							TagBackgroundColor:     On_White, // White background
 | 
				
			||||||
	LevelLua:     "\033[1;34m", // Bold Blue
 | 
							MessageColor:           White,    // Bold White text
 | 
				
			||||||
	LevelPrefix:  "\033[0;90m", // Regular Dark Grey
 | 
							MessageBackgroundColor: On_IRed,  // Intense Red background
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						LevelWarning: {
 | 
				
			||||||
 | 
							Tag:                    "WARNING",
 | 
				
			||||||
 | 
							TagColor:               BIOrange,   // Bold Intense Orange
 | 
				
			||||||
 | 
							TagBackgroundColor:     On_White,   // White background
 | 
				
			||||||
 | 
							MessageColor:           White,      // Bold White text
 | 
				
			||||||
 | 
							MessageBackgroundColor: On_IOrange, // Intense Orange background
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						LevelInfo: {
 | 
				
			||||||
 | 
							Tag:      "INFO",
 | 
				
			||||||
 | 
							TagColor: BGreen, // Bold Green
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						LevelDebug: {
 | 
				
			||||||
 | 
							Tag:      "DEBUG",
 | 
				
			||||||
 | 
							TagColor: BCyan, // Bold Cyan
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						LevelTrace: {
 | 
				
			||||||
 | 
							Tag:      "TRACE",
 | 
				
			||||||
 | 
							TagColor: BPurple, // Bold Purple
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						LevelLua: {
 | 
				
			||||||
 | 
							Tag:      "LUA",
 | 
				
			||||||
 | 
							TagColor: BBlue, // Bold Blue
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						LevelPrefix: {
 | 
				
			||||||
 | 
							Tag:      "PREFIX", // Used for coloring the user prefix
 | 
				
			||||||
 | 
							TagColor: BIBlack,  // Bold Intense Black (Dark Grey)
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ANSI Background Colors
 | 
					 | 
				
			||||||
var levelBackgroundColors = map[LogLevel]string{
 | 
					 | 
				
			||||||
	LevelError:   "\033[41m", // Red Background
 | 
					 | 
				
			||||||
	LevelWarning: "\033[43m", // Yellow Background
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ANSI Foreground Colors (adjusting for readability on backgrounds)
 | 
					 | 
				
			||||||
const FgWhiteBold = "\033[1;37m"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ResetColor is the ANSI code to reset text color
 | 
					 | 
				
			||||||
const ResetColor = "\033[0m"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Logger is our custom logger with level support
 | 
					// Logger is our custom logger with level support
 | 
				
			||||||
type Logger struct {
 | 
					type Logger struct {
 | 
				
			||||||
	mu            sync.Mutex
 | 
						mu            sync.Mutex
 | 
				
			||||||
@@ -115,8 +131,8 @@ func ParseLevel(levelStr string) LogLevel {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// String returns the string representation of the log level
 | 
					// String returns the string representation of the log level
 | 
				
			||||||
func (l LogLevel) String() string {
 | 
					func (l LogLevel) String() string {
 | 
				
			||||||
	if name, ok := levelNames[l]; ok {
 | 
						if name, ok := levelStyles[l]; ok {
 | 
				
			||||||
		return name
 | 
							return name.Tag
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return fmt.Sprintf("Level(%d)", l)
 | 
						return fmt.Sprintf("Level(%d)", l)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -318,56 +334,52 @@ func (l *Logger) formatMessage(level LogLevel, format string, args ...interface{
 | 
				
			|||||||
		fields = " " + strings.Join(pairs, " ")
 | 
							fields = " " + strings.Join(pairs, " ")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var levelColor, bgColor, msgFgColor, resetColor string
 | 
						var tagFgColor, tagBgColor, messageBgColor string
 | 
				
			||||||
	useBgColor := false // Flag to indicate if background color should be used
 | 
						useSpecialFormatting := false // Flag for levels with custom message background/foreground
 | 
				
			||||||
	if l.useColors {
 | 
						if l.useColors {
 | 
				
			||||||
		resetColor = ResetColor
 | 
							// Check if a message background color is defined for this level style
 | 
				
			||||||
		levelColor = levelColors[level] // Color for the level tag text ONLY
 | 
							if levelStyles[level].MessageBackgroundColor != "" {
 | 
				
			||||||
 | 
								useSpecialFormatting = true
 | 
				
			||||||
		if bg, ok := levelBackgroundColors[level]; ok { // Check if this level has a background color defined (ERROR/WARNING)
 | 
								// Retrieve all style components from the map
 | 
				
			||||||
			bgColor = bg
 | 
								tagFgColor = levelStyles[level].TagColor // Assign directly
 | 
				
			||||||
			msgFgColor = FgWhiteBold // Use bold white for the message part on colored background
 | 
								tagBgColor = levelStyles[level].TagBackgroundColor
 | 
				
			||||||
			useBgColor = true
 | 
								// messageFgColor = levelStyles[level].MessageColor
 | 
				
			||||||
 | 
								messageBgColor = levelStyles[level].MessageBackgroundColor
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// For other levels, message part uses default terminal color.
 | 
								// For other levels (INFO, DEBUG, etc.), only TagColor is guaranteed
 | 
				
			||||||
			// msgFgColor remains empty, bgColor remains empty.
 | 
								tagFgColor = levelStyles[level].TagColor // Use the defined tag color
 | 
				
			||||||
			// levelColor is still needed for the tag below.
 | 
								// tagBgColor, messageFgColor, messageBgColor remain empty (use terminal defaults)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var caller string
 | 
						var caller string
 | 
				
			||||||
	if l.flag&log.Lshortfile != 0 || l.flag&log.Llongfile != 0 {
 | 
						if l.flag&log.Lshortfile != 0 || l.flag&log.Llongfile != 0 {
 | 
				
			||||||
		// Find the actual caller by scanning up the stack
 | 
					 | 
				
			||||||
		// until we find a function outside the logger package
 | 
					 | 
				
			||||||
		var file string
 | 
							var file string
 | 
				
			||||||
		var line int
 | 
							var line int
 | 
				
			||||||
		var ok bool
 | 
							var ok bool
 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Start at a reasonable depth and scan up to 10 frames
 | 
							// Start at a reasonable depth and scan up to 10 frames
 | 
				
			||||||
		for depth := 4; depth < 15; depth++ {
 | 
							for depth := 4; depth < 15; depth++ {
 | 
				
			||||||
			_, file, line, ok = runtime.Caller(depth)
 | 
								_, file, line, ok = runtime.Caller(depth)
 | 
				
			||||||
			if !ok {
 | 
								if !ok {
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								// Check if the caller is within this logger package itself
 | 
				
			||||||
			// If the caller is not in the logger package, we found our caller
 | 
								if !strings.Contains(file, "main.go") && !strings.Contains(file, "colors.go") {
 | 
				
			||||||
			if !strings.Contains(file, "logger/logger.go") {
 | 
					 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			file = "???"
 | 
								file = "???"
 | 
				
			||||||
			line = 0
 | 
								line = 0
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if l.flag&log.Lshortfile != 0 {
 | 
							if l.flag&log.Lshortfile != 0 {
 | 
				
			||||||
			file = filepath.Base(file)
 | 
								file = filepath.Base(file)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							// Caller string - no background color applied here
 | 
				
			||||||
		caller = fmt.Sprintf("%-25s ", file+":"+strconv.Itoa(line))
 | 
							caller = fmt.Sprintf("%-25s ", file+":"+strconv.Itoa(line))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Format the timestamp with fixed width
 | 
						// Format the timestamp with fixed width - no background color applied here
 | 
				
			||||||
	var timeStr string
 | 
						var timeStr string
 | 
				
			||||||
	if l.flag&(log.Ldate|log.Ltime|log.Lmicroseconds) != 0 {
 | 
						if l.flag&(log.Ldate|log.Ltime|log.Lmicroseconds) != 0 {
 | 
				
			||||||
		t := time.Now()
 | 
							t := time.Now()
 | 
				
			||||||
@@ -383,41 +395,75 @@ func (l *Logger) formatMessage(level LogLevel, format string, args ...interface{
 | 
				
			|||||||
		timeStr = fmt.Sprintf("%-15s ", timeStr)
 | 
							timeStr = fmt.Sprintf("%-15s ", timeStr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add goroutine ID if enabled, with fixed width
 | 
						// Add goroutine ID if enabled, with fixed width - no background color applied here
 | 
				
			||||||
	var goroutineStr string
 | 
						var goroutineStr string
 | 
				
			||||||
	if l.showGoroutine {
 | 
						if l.showGoroutine {
 | 
				
			||||||
		goroutineID := GetGoroutineID()
 | 
							goroutineID := GetGoroutineID()
 | 
				
			||||||
		goroutineStr = fmt.Sprintf("[g:%-4s] ", goroutineID)
 | 
							goroutineStr = fmt.Sprintf("[g:%-4s] ", goroutineID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create a colored level indicator - color only the level name text, reset locally
 | 
						// --- Level Tag Formatting and Padding ---
 | 
				
			||||||
	levelStr := fmt.Sprintf("%s%s%s", levelColor, levelNames[level], resetColor)
 | 
						levelStr := levelStyles[level].Tag
 | 
				
			||||||
	levelColumn := fmt.Sprintf("%-20s", levelStr) // Pad the tag
 | 
						visibleTagContent := fmt.Sprintf("[%s]", levelStr)
 | 
				
			||||||
 | 
						visibleTagLen := len(visibleTagContent)
 | 
				
			||||||
 | 
						paddingWidth := 10 // Target width for the level column (tag + padding)
 | 
				
			||||||
 | 
						numSpaces := paddingWidth - visibleTagLen
 | 
				
			||||||
 | 
						if numSpaces < 0 {
 | 
				
			||||||
 | 
							numSpaces = 1 // Ensure at least one space
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						padding := strings.Repeat(" ", numSpaces)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var levelTagFormatted string
 | 
				
			||||||
 | 
						if useSpecialFormatting {
 | 
				
			||||||
 | 
							// ERROR/WARNING: Tag has specific background and foreground
 | 
				
			||||||
 | 
							levelTagFormatted = fmt.Sprintf("%s%s%s%s", tagBgColor, tagFgColor, visibleTagContent, Reset)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							// Other levels: Tag has standard foreground color only
 | 
				
			||||||
 | 
							levelTagFormatted = fmt.Sprintf("%s%s%s", tagFgColor, visibleTagContent, Reset)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						levelColumn := levelTagFormatted + padding // Combine formatted tag and padding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// --- User Prefix Formatting (part of message content for coloring purposes) ---
 | 
				
			||||||
	userPrefixStr := ""
 | 
						userPrefixStr := ""
 | 
				
			||||||
	if l.userPrefix != "" {
 | 
						if l.userPrefix != "" {
 | 
				
			||||||
		// Use default foreground color for prefix (dark grey), reset locally
 | 
							// Format the string part here, colors applied later if needed
 | 
				
			||||||
		prefixColor := levelColors[LevelPrefix]
 | 
							userPrefixStr = fmt.Sprintf("[%s] ", l.userPrefix)
 | 
				
			||||||
		userPrefixStr = fmt.Sprintf("%s[%s]%s ", prefixColor, l.userPrefix, resetColor)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Build the prefix part (timestamp, caller, goroutine, level tag, user prefix)
 | 
						// --- Message Content ---
 | 
				
			||||||
	// These parts will use default terminal colors or their specifically set colors (like level tag)
 | 
						messageContent := fmt.Sprintf("%s%s", msg, fields)
 | 
				
			||||||
	prefixPart := fmt.Sprintf("%s%s%s%s%s%s",
 | 
					 | 
				
			||||||
		l.prefix, timeStr, caller, goroutineStr, levelColumn, userPrefixStr)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Build the message part
 | 
						// --- Assemble Final String ---
 | 
				
			||||||
	messagePart := fmt.Sprintf("%s%s", msg, fields)
 | 
						var finalMsg strings.Builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Combine prefix and message, applying background/foreground ONLY to the message part
 | 
						// Part 1: Timestamp, Caller, Goroutine ID (always default colors)
 | 
				
			||||||
	if useBgColor {
 | 
						finalMsg.WriteString(l.prefix)
 | 
				
			||||||
		// Apply background and specific foreground ONLY to the message part
 | 
						finalMsg.WriteString(timeStr)
 | 
				
			||||||
		return fmt.Sprintf("%s%s%s%s%s", prefixPart, bgColor, msgFgColor, messagePart, resetColor)
 | 
						finalMsg.WriteString(caller)
 | 
				
			||||||
 | 
						finalMsg.WriteString(goroutineStr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Part 2: Level Column (already formatted with tag colors and padding)
 | 
				
			||||||
 | 
						finalMsg.WriteString(levelColumn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Part 3: User Prefix + Message Content (apply special formatting if needed)
 | 
				
			||||||
 | 
						if useSpecialFormatting {
 | 
				
			||||||
 | 
							// ERROR/WARNING: Apply message background and foreground to User Prefix + Message
 | 
				
			||||||
 | 
							finalMsg.WriteString(messageBgColor)
 | 
				
			||||||
 | 
							// finalMsg.WriteString(messageFgColor) // This doesn't work...? For some reason?
 | 
				
			||||||
 | 
							finalMsg.WriteString(userPrefixStr) // Write user prefix inside the colored block
 | 
				
			||||||
 | 
							finalMsg.WriteString(messageContent)
 | 
				
			||||||
 | 
							finalMsg.WriteString(Reset)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// For non-ERROR/WARNING, just combine prefix (with its colored tag) and the uncolored message part.
 | 
							// Other levels: User Prefix and Message content use default colors
 | 
				
			||||||
		// No additional color codes needed here for the message itself.
 | 
							// Apply specific color to user prefix if it exists
 | 
				
			||||||
		return fmt.Sprintf("%s%s", prefixPart, messagePart)
 | 
							if l.userPrefix != "" {
 | 
				
			||||||
 | 
								prefixColor := levelStyles[LevelPrefix].TagColor
 | 
				
			||||||
 | 
								finalMsg.WriteString(fmt.Sprintf("%s%s%s", prefixColor, userPrefixStr, Reset))
 | 
				
			||||||
 | 
							} // No else needed, if userPrefix is empty, userPrefixStr is "" anyway
 | 
				
			||||||
 | 
							finalMsg.WriteString(messageContent) // Append message with default colors
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return finalMsg.String()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// log logs a message at the specified level
 | 
					// log logs a message at the specified level
 | 
				
			||||||
@@ -573,3 +619,43 @@ func ShowGoroutine() bool {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return Default.ShowGoroutine()
 | 
						return Default.ShowGoroutine()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						Init(LevelDebug)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test basic logging
 | 
				
			||||||
 | 
						Debug("This is a debug message")
 | 
				
			||||||
 | 
						Info("This is an info message")
 | 
				
			||||||
 | 
						Warning("This is a warning message")
 | 
				
			||||||
 | 
						Error("This is an error message")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test logging with fields
 | 
				
			||||||
 | 
						logger := WithField("user", "testuser")
 | 
				
			||||||
 | 
						logger.Info("User logged in")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test logging with multiple fields
 | 
				
			||||||
 | 
						fields := map[string]interface{}{
 | 
				
			||||||
 | 
							"user": "testuser",
 | 
				
			||||||
 | 
							"role": "admin",
 | 
				
			||||||
 | 
							"id":   12345,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						WithFields(fields).Info("User details")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test error logging with fields
 | 
				
			||||||
 | 
						WithField("error", "connection failed").Error("Database error")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger.WithPrefix("CUSTOM").Info("This is a message with a custom prefix")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test goroutine ID display
 | 
				
			||||||
 | 
						SetShowGoroutine(true)
 | 
				
			||||||
 | 
						Info("This message should show goroutine ID")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test different log levels
 | 
				
			||||||
 | 
						SetLevel(LevelInfo)
 | 
				
			||||||
 | 
						Debug("This debug message should not appear")
 | 
				
			||||||
 | 
						Info("This info message should appear")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test with custom prefix
 | 
				
			||||||
 | 
						WithField("prefix", "custom").Info("Message with custom prefix")
 | 
				
			||||||
 | 
						Lua("This is a Lua message")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user