|
| 1 | +// Package logging provides a simple logging library with support for |
| 2 | +// multiple log levels, custom prefixes, colored output, and customizable |
| 3 | +// output streams. |
| 4 | +package logging |
| 5 | + |
| 6 | +import ( |
| 7 | + "fmt" |
| 8 | + "io" |
| 9 | + "os" |
| 10 | + "time" |
| 11 | +) |
| 12 | + |
| 13 | +// ANSI color codes for different log levels |
| 14 | +const ( |
| 15 | + ColorReset = "\033[0m" // Reset to default color |
| 16 | + ColorBlue = "\033[34m" // Blue color for INFO level logs |
| 17 | + ColorGreen = "\033[32m" // Green color for DEBUG level logs |
| 18 | + ColorYellow = "\033[33m" // Yellow color for WARN level logs |
| 19 | + ColorRed = "\033[31m" // Red color for ERROR level logs |
| 20 | +) |
| 21 | + |
| 22 | +// LogLevel represents the severity level of a log message. |
| 23 | +type LogLevel int |
| 24 | + |
| 25 | +// Defined log levels in increasing order of severity. |
| 26 | +const ( |
| 27 | + DEBUG LogLevel = iota // DEBUG is used for detailed information during development. |
| 28 | + INFO // INFO is used for general informational messages. |
| 29 | + WARN // WARN is used for warnings that are not critical. |
| 30 | + ERROR // ERROR is used for critical error messages. |
| 31 | +) |
| 32 | + |
| 33 | +// Logger is a configurable logging instance that supports multiple log levels, |
| 34 | +// optional colored output, and custom prefixes for log messages. |
| 35 | +type Logger struct { |
| 36 | + minLevel LogLevel // Minimum log level for messages to be logged |
| 37 | + prefix string // Prefix to prepend to all log messages |
| 38 | + output io.Writer // Output destination for log messages (e.g., os.Stdout) |
| 39 | + disableColors bool // Flag to disable color codes (useful for testing or non-ANSI terminals) |
| 40 | +} |
| 41 | + |
| 42 | +// NewLogger creates and returns a new Logger instance with the specified prefix, |
| 43 | +// minimum log level, and output destination. If output is nil, os.Stdout is used |
| 44 | +// as the default destination. |
| 45 | +// |
| 46 | +// Parameters: |
| 47 | +// - prefix: A string prefix that will appear in all log messages. |
| 48 | +// - minLevel: The minimum log level for a message to be logged. |
| 49 | +// - output: The io.Writer to which log messages will be written. |
| 50 | +// |
| 51 | +// Returns: |
| 52 | +// |
| 53 | +// A pointer to a configured Logger instance. |
| 54 | +func NewLogger(prefix string, minLevel LogLevel, output io.Writer) *Logger { |
| 55 | + if output == nil { |
| 56 | + output = os.Stdout // Default to standard output |
| 57 | + } |
| 58 | + return &Logger{ |
| 59 | + minLevel: minLevel, |
| 60 | + prefix: prefix, |
| 61 | + output: output, |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +// log handles the core logic of logging messages. It applies the appropriate |
| 66 | +// color coding (if enabled), formats the log message with a timestamp and prefix, |
| 67 | +// and writes it to the configured output destination. |
| 68 | +// |
| 69 | +// Parameters: |
| 70 | +// - level: The LogLevel of the message being logged. |
| 71 | +// - message: The actual log message to be recorded. |
| 72 | +func (l *Logger) log(level LogLevel, message string) { |
| 73 | + if level < l.minLevel { |
| 74 | + return |
| 75 | + } |
| 76 | + |
| 77 | + // Determine the color and level string for the log level |
| 78 | + color := "" |
| 79 | + levelStr := "" |
| 80 | + switch level { |
| 81 | + case INFO: |
| 82 | + color = ColorBlue |
| 83 | + levelStr = "INFO" |
| 84 | + case DEBUG: |
| 85 | + color = ColorGreen |
| 86 | + levelStr = "DEBUG" |
| 87 | + case WARN: |
| 88 | + color = ColorYellow |
| 89 | + levelStr = "WARN" |
| 90 | + case ERROR: |
| 91 | + color = ColorRed |
| 92 | + levelStr = "ERROR" |
| 93 | + } |
| 94 | + |
| 95 | + // Disable color if the flag is set |
| 96 | + if l.disableColors { |
| 97 | + color = "" |
| 98 | + } |
| 99 | + |
| 100 | + // Format the timestamp for the log message |
| 101 | + timestamp := time.Now().Format("2006-01-02 15:04:05") |
| 102 | + |
| 103 | + // Construct the formatted log message |
| 104 | + logMessage := fmt.Sprintf("%s[%s] [%s] %s: %s%s\n", color, timestamp, levelStr, l.prefix, message, ColorReset) |
| 105 | + |
| 106 | + // Write the log message to the configured output |
| 107 | + _, err := fmt.Fprint(l.output, logMessage) |
| 108 | + if err != nil { |
| 109 | + fmt.Fprintf(os.Stderr, "Failed to write log: %v\n", err) |
| 110 | + } |
| 111 | +} |
| 112 | + |
| 113 | +// Info logs a message at the INFO level. |
| 114 | +// |
| 115 | +// Parameters: |
| 116 | +// - message: The informational message to log. |
| 117 | +func (l *Logger) Info(message string) { |
| 118 | + l.log(INFO, message) |
| 119 | +} |
| 120 | + |
| 121 | +// Debug logs a message at the DEBUG level. |
| 122 | +// |
| 123 | +// Parameters: |
| 124 | +// - message: The debug message to log. |
| 125 | +func (l *Logger) Debug(message string) { |
| 126 | + l.log(DEBUG, message) |
| 127 | +} |
| 128 | + |
| 129 | +// Warn logs a message at the WARN level. |
| 130 | +// |
| 131 | +// Parameters: |
| 132 | +// - message: The warning message to log. |
| 133 | +func (l *Logger) Warn(message string) { |
| 134 | + l.log(WARN, message) |
| 135 | +} |
| 136 | + |
| 137 | +// Error logs a message at the ERROR level. |
| 138 | +// |
| 139 | +// Parameters: |
| 140 | +// - message: The error message to log. |
| 141 | +func (l *Logger) Error(message string) { |
| 142 | + l.log(ERROR, message) |
| 143 | +} |
0 commit comments