Refactor logger to support multiple output writers and disable stdout
This commit is contained in:
57
main.go
57
main.go
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hexops/valast"
|
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@@ -14,6 +13,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hexops/valast"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Enable turning colors on and off maybe even per stream?
|
// TODO: Enable turning colors on and off maybe even per stream?
|
||||||
@@ -97,7 +98,7 @@ var levelStyles = map[LogLevel]LevelStyle{
|
|||||||
// 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
|
||||||
out io.Writer
|
out []io.Writer
|
||||||
currentLevel LogLevel
|
currentLevel LogLevel
|
||||||
prefix string
|
prefix string
|
||||||
userPrefix string
|
userPrefix string
|
||||||
@@ -150,7 +151,7 @@ func (l LogLevel) String() string {
|
|||||||
// New creates a new Logger instance
|
// New creates a new Logger instance
|
||||||
func New(out io.Writer, prefix string, flag int) *Logger {
|
func New(out io.Writer, prefix string, flag int) *Logger {
|
||||||
return &Logger{
|
return &Logger{
|
||||||
out: out,
|
out: []io.Writer{out},
|
||||||
currentLevel: defaultLogLevel,
|
currentLevel: defaultLogLevel,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
userPrefix: "",
|
userPrefix: "",
|
||||||
@@ -216,7 +217,7 @@ func (l *Logger) ShowGoroutine() bool {
|
|||||||
// WithField adds a field to the logger's context
|
// WithField adds a field to the logger's context
|
||||||
func (l *Logger) WithField(key string, value interface{}) *Logger {
|
func (l *Logger) WithField(key string, value interface{}) *Logger {
|
||||||
newLogger := &Logger{
|
newLogger := &Logger{
|
||||||
out: l.out,
|
out: append([]io.Writer(nil), l.out...),
|
||||||
currentLevel: l.currentLevel,
|
currentLevel: l.currentLevel,
|
||||||
prefix: l.prefix,
|
prefix: l.prefix,
|
||||||
userPrefix: l.userPrefix,
|
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
|
// WithFields adds multiple fields to the logger's context
|
||||||
func (l *Logger) WithFields(fields map[string]interface{}) *Logger {
|
func (l *Logger) WithFields(fields map[string]interface{}) *Logger {
|
||||||
newLogger := &Logger{
|
newLogger := &Logger{
|
||||||
out: l.out,
|
out: append([]io.Writer(nil), l.out...),
|
||||||
currentLevel: l.currentLevel,
|
currentLevel: l.currentLevel,
|
||||||
prefix: l.prefix,
|
prefix: l.prefix,
|
||||||
userPrefix: l.userPrefix,
|
userPrefix: l.userPrefix,
|
||||||
@@ -271,7 +272,7 @@ func (l *Logger) WithPrefix(prefix string) *Logger {
|
|||||||
l = Default
|
l = Default
|
||||||
}
|
}
|
||||||
newLogger := &Logger{
|
newLogger := &Logger{
|
||||||
out: l.out,
|
out: append([]io.Writer(nil), l.out...),
|
||||||
currentLevel: l.currentLevel,
|
currentLevel: l.currentLevel,
|
||||||
prefix: l.prefix,
|
prefix: l.prefix,
|
||||||
userPrefix: strings.TrimSpace(l.userPrefix + " " + prefix),
|
userPrefix: strings.TrimSpace(l.userPrefix + " " + prefix),
|
||||||
@@ -301,7 +302,7 @@ func (l *Logger) ToFile(filename string) *Logger {
|
|||||||
l = Default
|
l = Default
|
||||||
}
|
}
|
||||||
newLogger := &Logger{
|
newLogger := &Logger{
|
||||||
out: io.MultiWriter(l.out, file),
|
out: append([]io.Writer(nil), l.out...),
|
||||||
currentLevel: l.currentLevel,
|
currentLevel: l.currentLevel,
|
||||||
prefix: l.prefix,
|
prefix: l.prefix,
|
||||||
userPrefix: l.userPrefix,
|
userPrefix: l.userPrefix,
|
||||||
@@ -311,6 +312,12 @@ func (l *Logger) ToFile(filename string) *Logger {
|
|||||||
defaultFields: make(map[string]interface{}),
|
defaultFields: make(map[string]interface{}),
|
||||||
showGoroutine: l.showGoroutine,
|
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
|
return newLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,7 +495,9 @@ func (l *Logger) log(level LogLevel, format string, args ...interface{}) {
|
|||||||
|
|
||||||
// Get formatted message with potential background color
|
// Get formatted message with potential background color
|
||||||
msg := l.formatMessage(level, format, args...)
|
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
|
// Error logs an error message
|
||||||
@@ -659,6 +668,38 @@ func ShowGoroutine() bool {
|
|||||||
return Default.ShowGoroutine()
|
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() {
|
func main() {
|
||||||
Init(LevelDebug)
|
Init(LevelDebug)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user