Refactor logger to support multiple output writers and disable stdout

This commit is contained in:
2025-08-11 14:29:35 +02:00
parent 1712042f64
commit 02fed6e55f

65
main.go
View File

@@ -4,7 +4,6 @@ import (
"bytes"
"flag"
"fmt"
"github.com/hexops/valast"
"io"
"log"
"os"
@@ -14,6 +13,8 @@ import (
"strings"
"sync"
"time"
"github.com/hexops/valast"
)
// TODO: Enable turning colors on and off maybe even per stream?
@@ -79,10 +80,10 @@ var levelStyles = map[LogLevel]LevelStyle{
TagColor: BPurple, // Bold Purple
},
LevelDump: {
Tag: "DUMP",
TagColor: BIMagenta, // Bold Intense Magenta
TagBackgroundColor: On_White, // White background
MessageColor: IMagenta, // White text
Tag: "DUMP",
TagColor: BIMagenta, // Bold Intense Magenta
TagBackgroundColor: On_White, // White background
MessageColor: IMagenta, // White text
},
LevelLua: {
Tag: "LUA",
@@ -97,7 +98,7 @@ var levelStyles = map[LogLevel]LevelStyle{
// Logger is our custom logger with level support
type Logger struct {
mu sync.Mutex
out io.Writer
out []io.Writer
currentLevel LogLevel
prefix string
userPrefix string
@@ -150,7 +151,7 @@ func (l LogLevel) String() string {
// New creates a new Logger instance
func New(out io.Writer, prefix string, flag int) *Logger {
return &Logger{
out: out,
out: []io.Writer{out},
currentLevel: defaultLogLevel,
prefix: prefix,
userPrefix: "",
@@ -216,7 +217,7 @@ func (l *Logger) ShowGoroutine() bool {
// WithField adds a field to the logger's context
func (l *Logger) WithField(key string, value interface{}) *Logger {
newLogger := &Logger{
out: l.out,
out: append([]io.Writer(nil), l.out...),
currentLevel: l.currentLevel,
prefix: l.prefix,
userPrefix: l.userPrefix,
@@ -240,7 +241,7 @@ func (l *Logger) WithField(key string, value interface{}) *Logger {
// WithFields adds multiple fields to the logger's context
func (l *Logger) WithFields(fields map[string]interface{}) *Logger {
newLogger := &Logger{
out: l.out,
out: append([]io.Writer(nil), l.out...),
currentLevel: l.currentLevel,
prefix: l.prefix,
userPrefix: l.userPrefix,
@@ -271,7 +272,7 @@ func (l *Logger) WithPrefix(prefix string) *Logger {
l = Default
}
newLogger := &Logger{
out: l.out,
out: append([]io.Writer(nil), l.out...),
currentLevel: l.currentLevel,
prefix: l.prefix,
userPrefix: strings.TrimSpace(l.userPrefix + " " + prefix),
@@ -301,7 +302,7 @@ func (l *Logger) ToFile(filename string) *Logger {
l = Default
}
newLogger := &Logger{
out: io.MultiWriter(l.out, file),
out: append([]io.Writer(nil), l.out...),
currentLevel: l.currentLevel,
prefix: l.prefix,
userPrefix: l.userPrefix,
@@ -311,6 +312,12 @@ func (l *Logger) ToFile(filename string) *Logger {
defaultFields: make(map[string]interface{}),
showGoroutine: l.showGoroutine,
}
// Copy existing fields
for k, v := range l.defaultFields {
newLogger.defaultFields[k] = v
}
// Append the new file writer
newLogger.out = append(newLogger.out, file)
return newLogger
}
@@ -488,7 +495,9 @@ func (l *Logger) log(level LogLevel, format string, args ...interface{}) {
// Get formatted message with potential background color
msg := l.formatMessage(level, format, args...)
fmt.Fprintln(l.out, msg)
for _, w := range l.out {
fmt.Fprintln(w, msg)
}
}
// Error logs an error message
@@ -659,6 +668,38 @@ func ShowGoroutine() bool {
return Default.ShowGoroutine()
}
func (l *Logger) NoStdout() *Logger {
if Default == nil {
Init(defaultLogLevel)
}
if l == nil {
l = Default
}
newLogger := &Logger{
out: nil,
currentLevel: l.currentLevel,
prefix: l.prefix,
userPrefix: l.userPrefix,
flag: l.flag,
useColors: l.useColors,
callerOffset: l.callerOffset,
defaultFields: make(map[string]interface{}),
showGoroutine: l.showGoroutine,
}
// Copy existing fields
for k, v := range l.defaultFields {
newLogger.defaultFields[k] = v
}
// Keep all writers except stdout
for _, w := range l.out {
if w == os.Stdout {
continue
}
newLogger.out = append(newLogger.out, w)
}
return newLogger
}
func main() {
Init(LevelDebug)