From 423b832964fe565f5ef797b23db675537292d920 Mon Sep 17 00:00:00 2001 From: Bill Kehoe Date: Tue, 16 Aug 2022 12:51:52 -0400 Subject: [PATCH] Fix non-reentrant use of LogWriter Add File.Close method to FileLogWriter to close file on Close Fix missing argument in NewFileLogger calls Remove newlines from error messages Add go modules support Clean up go linter warnings Restructure examples folder so no duplicate use of main() in same forlder --- .vscode/launch.json | 22 +++ .../ConsoleLogWriter_Manual.go | 4 +- .../FileLogWriter_Manual.go | 12 +- examples/{ => JsonCfgTest}/JsonCfgTest.go | 2 +- .../LogInjectionExample.go | 8 +- .../SimpleNetLogServer.go | 0 .../SocketLogWriter_Manual.go | 4 +- .../XMLConfigurationExample.go | 2 +- examples/example.xml | 1 + filelog.go | 9 +- go.mod | 5 + go.sum | 2 + jsonconfig.go | 2 +- log4go.go | 49 ++++--- log4go_test.go | 129 +++++++++--------- pattlog.go | 2 +- socklog.go | 4 +- wrapper.go | 9 +- 18 files changed, 152 insertions(+), 114 deletions(-) create mode 100644 .vscode/launch.json rename examples/{ => ConsoleLogWriter_Manual}/ConsoleLogWriter_Manual.go (86%) rename examples/{ => FileLogWriter_Manual}/FileLogWriter_Manual.go (85%) rename examples/{ => JsonCfgTest}/JsonCfgTest.go (95%) rename examples/{ => LogInjectionExample}/LogInjectionExample.go (93%) rename examples/{ => SimpleNetLogServer}/SimpleNetLogServer.go (100%) rename examples/{ => SimpleNetLogServer_Manual}/SocketLogWriter_Manual.go (91%) rename examples/{ => XMLConfigurationExample}/XMLConfigurationExample.go (91%) create mode 100644 go.mod create mode 100644 go.sum diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..250a7e5 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ConsoleLogWriter_Manual", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceRoot}/examples/ConsoleLogWriter_Manual/ConsoleLogWriter_Manual.go", + }, + { + "name": "FileLogWriter_Manual", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceRoot}/examples/FileLogWriter_Manual/FileLogWriter_Manual.go", + }, + ] +} \ No newline at end of file diff --git a/examples/ConsoleLogWriter_Manual.go b/examples/ConsoleLogWriter_Manual/ConsoleLogWriter_Manual.go similarity index 86% rename from examples/ConsoleLogWriter_Manual.go rename to examples/ConsoleLogWriter_Manual/ConsoleLogWriter_Manual.go index 698dd33..fc3607b 100644 --- a/examples/ConsoleLogWriter_Manual.go +++ b/examples/ConsoleLogWriter_Manual/ConsoleLogWriter_Manual.go @@ -2,9 +2,9 @@ package main import ( "time" -) -import l4g "code.google.com/p/log4go" + l4g "github.com/wvkehoe/log4go" +) func main() { log := l4g.NewLogger() diff --git a/examples/FileLogWriter_Manual.go b/examples/FileLogWriter_Manual/FileLogWriter_Manual.go similarity index 85% rename from examples/FileLogWriter_Manual.go rename to examples/FileLogWriter_Manual/FileLogWriter_Manual.go index efd596a..66f4c42 100644 --- a/examples/FileLogWriter_Manual.go +++ b/examples/FileLogWriter_Manual/FileLogWriter_Manual.go @@ -6,9 +6,9 @@ import ( "io" "os" "time" -) -import l4g "code.google.com/p/log4go" + l4g "github.com/wvkehoe/log4go" +) const ( filename = "flw.log" @@ -19,17 +19,17 @@ func main() { log := l4g.NewLogger() // Create a default logger that is logging messages of FINE or higher - log.AddFilter("file", l4g.FINE, l4g.NewFileLogWriter(filename, false)) + log.AddFilter("file", l4g.FINE, l4g.NewFileLogWriter(filename, false, false)) log.Close() /* Can also specify manually via the following: (these are the defaults) */ - flw := l4g.NewFileLogWriter(filename, false) - flw.SetFormat("[%D %T] [%L] (%S) %M") + flw := l4g.NewFileLogWriter(filename, false, false) + flw.SetFormat("[%D %T] [%L] (%C) (%S) %M") flw.SetRotate(false) flw.SetRotateSize(0) flw.SetRotateLines(0) flw.SetRotateDaily(false) - log.AddFilter("file", l4g.FINE, flw) + log.AddFilter("file", l4g.FINE, flw, "com.foobar") // Log some experimental messages log.Finest("Everything is created now (notice that I will not be printing to the file)") diff --git a/examples/JsonCfgTest.go b/examples/JsonCfgTest/JsonCfgTest.go similarity index 95% rename from examples/JsonCfgTest.go rename to examples/JsonCfgTest/JsonCfgTest.go index 459ee32..8e8d17a 100644 --- a/examples/JsonCfgTest.go +++ b/examples/JsonCfgTest/JsonCfgTest.go @@ -1,7 +1,7 @@ package main import ( - log "github.com/jeanphorn/log4go" + log "github.com/wvkehoe/log4go" ) func main() { diff --git a/examples/LogInjectionExample.go b/examples/LogInjectionExample/LogInjectionExample.go similarity index 93% rename from examples/LogInjectionExample.go rename to examples/LogInjectionExample/LogInjectionExample.go index cea9ebd..33e6dfe 100644 --- a/examples/LogInjectionExample.go +++ b/examples/LogInjectionExample/LogInjectionExample.go @@ -6,9 +6,9 @@ import ( "io" "os" "time" -) -import l4g "log4go" + l4g "github.com/wvkehoe/log4go" +) const ( filename = "loginjection.log" @@ -39,7 +39,7 @@ func main() { log.AddFilter("file", l4g.FINE, flw) // Log some experimental messages - for _,message := range(user_input) { + for _, message := range user_input { log.Info(message) } @@ -51,7 +51,7 @@ func main() { // Close the log log.Close() - // Print what was logged to the file + // Print what was logged to the file fd, err := os.Open(filename) if err != nil { fmt.Printf("Error reopening file: %s", filename) diff --git a/examples/SimpleNetLogServer.go b/examples/SimpleNetLogServer/SimpleNetLogServer.go similarity index 100% rename from examples/SimpleNetLogServer.go rename to examples/SimpleNetLogServer/SimpleNetLogServer.go diff --git a/examples/SocketLogWriter_Manual.go b/examples/SimpleNetLogServer_Manual/SocketLogWriter_Manual.go similarity index 91% rename from examples/SocketLogWriter_Manual.go rename to examples/SimpleNetLogServer_Manual/SocketLogWriter_Manual.go index 400b698..7fd6959 100644 --- a/examples/SocketLogWriter_Manual.go +++ b/examples/SimpleNetLogServer_Manual/SocketLogWriter_Manual.go @@ -2,9 +2,9 @@ package main import ( "time" -) -import l4g "code.google.com/p/log4go" + l4g "github.com/wvkehoe/log4go" +) func main() { log := l4g.NewLogger() diff --git a/examples/XMLConfigurationExample.go b/examples/XMLConfigurationExample/XMLConfigurationExample.go similarity index 91% rename from examples/XMLConfigurationExample.go rename to examples/XMLConfigurationExample/XMLConfigurationExample.go index 29abefd..387aa8a 100644 --- a/examples/XMLConfigurationExample.go +++ b/examples/XMLConfigurationExample/XMLConfigurationExample.go @@ -1,7 +1,7 @@ package main import ( - l4g "github.com/jeanphorn/log4go" + l4g "github.com/wvkehoe/log4go" ) func main() { diff --git a/examples/example.xml b/examples/example.xml index e791278..a43cd35 100644 --- a/examples/example.xml +++ b/examples/example.xml @@ -1,3 +1,4 @@ + stdout diff --git a/filelog.go b/filelog.go index 9a3db22..d8a5764 100644 --- a/filelog.go +++ b/filelog.go @@ -5,8 +5,8 @@ package log4go import ( "fmt" "os" - "time" "strings" + "time" ) // This log writer sends output to a file @@ -41,7 +41,7 @@ type FileLogWriter struct { maxbackup int // Sanitize newlines to prevent log injection - sanitize bool + sanitize bool } // This is the FileLogWriter's output method @@ -52,6 +52,7 @@ func (w *FileLogWriter) LogWrite(rec *LogRecord) { func (w *FileLogWriter) Close() { close(w.rec) w.file.Sync() + w.file.Close() } // NewFileLogWriter creates a new LogWriter which writes to the given file and @@ -169,7 +170,7 @@ func (w *FileLogWriter) intRotate() error { // Rename the file to its newfound home err = os.Rename(w.filename, fname) if err != nil { - return fmt.Errorf("Rotate: %s\n", err) + return fmt.Errorf("Rotate: %s", err) } } else if !w.daily { num = w.maxbackup - 1 @@ -186,7 +187,7 @@ func (w *FileLogWriter) intRotate() error { err = os.Rename(w.filename, fname) // return error if the last file checked still existed if err != nil { - return fmt.Errorf("Rotate: %s\n", err) + return fmt.Errorf("Rotate: %s", err) } } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2c23b4c --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/wvkehoe/log4go + +go 1.18 + +require github.com/toolkits/file v0.0.0-20160325033739-a5b3c5147e07 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0f8f476 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/toolkits/file v0.0.0-20160325033739-a5b3c5147e07 h1:d/VUIMNTk65Xz69htmRPNfjypq2uNRqVsymcXQu6kKk= +github.com/toolkits/file v0.0.0-20160325033739-a5b3c5147e07/go.mod h1:FbXpUxsx5in7z/OrWFDdhYetOy3/VGIJsVHN9G7RUPA= diff --git a/jsonconfig.go b/jsonconfig.go index 3dff299..f4de2fc 100644 --- a/jsonconfig.go +++ b/jsonconfig.go @@ -76,7 +76,7 @@ func (log Logger) LoadJsonConfiguration(filename string) { os.Exit(1) } } else { - content = string(dst.Bytes()) + content = dst.String() } err = json.Unmarshal([]byte(content), &lc) diff --git a/log4go.go b/log4go.go index 2eab379..738af26 100644 --- a/log4go.go +++ b/log4go.go @@ -216,19 +216,21 @@ func (log Logger) intLogf(lvl Level, format string, args ...interface{}) { msg = fmt.Sprintf(format, args...) } - // Make the log record - rec := &LogRecord{ - Level: lvl, - Created: time.Now(), - Source: src, - Message: msg, - } + now := time.Now() // Dispatch the logs for _, filt := range log { if lvl < filt.Level { continue } + // Make the log record + rec := &LogRecord{ + Level: lvl, + Created: now, + Source: src, + Message: msg, + Category: filt.Category, + } filt.LogWrite(rec) } } @@ -254,20 +256,21 @@ func (log Logger) intLogc(lvl Level, closure func() string) { if ok { src = fmt.Sprintf("%s:%d", runtime.FuncForPC(pc).Name(), lineno) } - - // Make the log record - rec := &LogRecord{ - Level: lvl, - Created: time.Now(), - Source: src, - Message: closure(), - } + now := time.Now() // Dispatch the logs for _, filt := range log { if lvl < filt.Level { continue } + // Make the log record + rec := &LogRecord{ + Level: lvl, + Created: now, + Source: src, + Category: filt.Category, + Message: closure(), + } filt.LogWrite(rec) } } @@ -287,19 +290,21 @@ func (log Logger) Log(lvl Level, source, message string) { return } - // Make the log record - rec := &LogRecord{ - Level: lvl, - Created: time.Now(), - Source: source, - Message: message, - } + now := time.Now() // Dispatch the logs for _, filt := range log { if lvl < filt.Level { continue } + // Make the log record + rec := &LogRecord{ + Level: lvl, + Created: now, + Source: source, + Message: message, + Category: filt.Category, + } filt.LogWrite(rec) } } diff --git a/log4go_test.go b/log4go_test.go index 89d9981..775355a 100644 --- a/log4go_test.go +++ b/log4go_test.go @@ -134,16 +134,19 @@ func TestConsoleLogWriter(t *testing.T) { buf := make([]byte, 1024) - for _, test := range logRecordWriteTests { - name := test.Test + go func() { + for _, test := range logRecordWriteTests { + name := test.Test + n, _ := r.Read(buf) + if got, want := string(buf[:n]), test.Console; got != want { + t.Errorf("%s: got %q", name, got) + t.Errorf("%s: want %q", name, want) + } + } + }() + for _, test := range logRecordWriteTests { console.LogWrite(test.Record) - n, _ := r.Read(buf) - - if got, want := string(buf[:n]), test.Console; got != want { - t.Errorf("%s: got %q", name, got) - t.Errorf("%s: want %q", name, want) - } } } @@ -153,7 +156,7 @@ func TestFileLogWriter(t *testing.T) { }(LogBufferLength) LogBufferLength = 0 - w := NewFileLogWriter(testLogFile, false) + w := NewFileLogWriter(testLogFile, false, false) if w == nil { t.Fatalf("Invalid return: w should not be nil") } @@ -176,7 +179,7 @@ func TestXMLLogWriter(t *testing.T) { }(LogBufferLength) LogBufferLength = 0 - w := NewXMLLogWriter(testLogFile, false) + w := NewXMLLogWriter(testLogFile, false, false) if w == nil { t.Fatalf("Invalid return: w should not be nil") } @@ -261,7 +264,7 @@ func TestLogOutput(t *testing.T) { l := make(Logger) // Delete and open the output log without a timestamp (for a constant md5sum) - l.AddFilter("file", FINEST, NewFileLogWriter(testLogFile, false).SetFormat("[%L] %M")) + l.AddFilter("file", FINEST, NewFileLogWriter(testLogFile, false, false).SetFormat("[%L] %M")) defer os.Remove(testLogFile) // Send some log messages @@ -343,53 +346,55 @@ func TestXMLConfig(t *testing.T) { t.Fatalf("Could not open %s for writing: %s", configfile, err) } - fmt.Fprintln(fd, "") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " stdout") - fmt.Fprintln(fd, " console") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " DEBUG") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " file") - fmt.Fprintln(fd, " file") - fmt.Fprintln(fd, " FINEST") - fmt.Fprintln(fd, " test.log") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " [%D %T] [%L] (%S) %M") - fmt.Fprintln(fd, " false ") - fmt.Fprintln(fd, " 0M ") - fmt.Fprintln(fd, " 0K ") - fmt.Fprintln(fd, " true ") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " xmllog") - fmt.Fprintln(fd, " xml") - fmt.Fprintln(fd, " TRACE") - fmt.Fprintln(fd, " trace.xml") - fmt.Fprintln(fd, " true ") - fmt.Fprintln(fd, " 100M ") - fmt.Fprintln(fd, " 6K ") - fmt.Fprintln(fd, " false ") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, " donotopen") - fmt.Fprintln(fd, " socket") - fmt.Fprintln(fd, " FINEST") - fmt.Fprintln(fd, " 192.168.1.255:12124 ") - fmt.Fprintln(fd, " udp ") - fmt.Fprintln(fd, " ") - fmt.Fprintln(fd, "") + const config = ` + + stdout + console + + DEBUG + + + file + file + FINEST + test.log + + [%%D %%T] [%%L] (%%S) %%M + false + 0M + 0K + true + + + xmllog + xml + TRACE + trace.xml + true + 100M + 6K + false + + + donotopen + socket + FINEST + 192.168.1.255:12124 + udp + +%s +` + fmt.Fprintf(fd, config, "") fd.Close() log := make(Logger) @@ -510,7 +515,7 @@ func BenchmarkConsoleUtilNotLog(b *testing.B) { func BenchmarkFileLog(b *testing.B) { sl := make(Logger) b.StopTimer() - sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false)) + sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false, false)) b.StartTimer() for i := 0; i < b.N; i++ { sl.Log(WARNING, "here", "This is a log message") @@ -522,7 +527,7 @@ func BenchmarkFileLog(b *testing.B) { func BenchmarkFileNotLogged(b *testing.B) { sl := make(Logger) b.StopTimer() - sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false)) + sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false, false)) b.StartTimer() for i := 0; i < b.N; i++ { sl.Log(DEBUG, "here", "This is a log message") @@ -534,7 +539,7 @@ func BenchmarkFileNotLogged(b *testing.B) { func BenchmarkFileUtilLog(b *testing.B) { sl := make(Logger) b.StopTimer() - sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false)) + sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false, false)) b.StartTimer() for i := 0; i < b.N; i++ { sl.Info("%s is a log message", "This") @@ -546,7 +551,7 @@ func BenchmarkFileUtilLog(b *testing.B) { func BenchmarkFileUtilNotLog(b *testing.B) { sl := make(Logger) b.StopTimer() - sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false)) + sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false, false)) b.StartTimer() for i := 0; i < b.N; i++ { sl.Debug("%s is a log message", "This") diff --git a/pattlog.go b/pattlog.go index a01db21..89ed88a 100644 --- a/pattlog.go +++ b/pattlog.go @@ -136,7 +136,7 @@ func (w FormatLogWriter) Close() { func changeDttmFormat(format string, rec *LogRecord) []byte { formatByte := []byte(format) - r := regexp.MustCompile("\\%D\\{(.*?)\\}") + r := regexp.MustCompile(`\%D\{(.*?)\}`) i := 0 formatByte = r.ReplaceAllFunc(formatByte, func(s []byte) []byte { if i < 2 { diff --git a/socklog.go b/socklog.go index 1d224a9..2c695cf 100644 --- a/socklog.go +++ b/socklog.go @@ -41,13 +41,13 @@ func NewSocketLogWriter(proto, hostport string) SocketLogWriter { // Marshall into JSON js, err := json.Marshal(rec) if err != nil { - fmt.Fprint(os.Stderr, "SocketLogWriter(%q): %s", hostport, err) + fmt.Fprintf(os.Stderr, "SocketLogWriter(%q): %s", hostport, err) return } _, err = sock.Write(js) if err != nil { - fmt.Fprint(os.Stderr, "SocketLogWriter(%q): %s", hostport, err) + fmt.Fprintf(os.Stderr, "SocketLogWriter(%q): %s", hostport, err) return } } diff --git a/wrapper.go b/wrapper.go index c309e33..441ce15 100644 --- a/wrapper.go +++ b/wrapper.go @@ -217,7 +217,7 @@ func Warn(arg0 interface{}, args ...interface{}) error { case string: // Use the string as a format string Global.intLogf(lvl, first, args...) - return errors.New(fmt.Sprintf(first, args...)) + return fmt.Errorf(first, args...) case func() string: // Log the closure (no other arguments used) str := first() @@ -228,7 +228,6 @@ func Warn(arg0 interface{}, args ...interface{}) error { Global.intLogf(lvl, fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...) return errors.New(fmt.Sprint(first) + fmt.Sprintf(strings.Repeat(" %v", len(args)), args...)) } - return nil } // Utility for error log messages (returns an error for easy function returns) (see Debug() for parameter explanation) @@ -242,7 +241,7 @@ func Error(arg0 interface{}, args ...interface{}) error { case string: // Use the string as a format string Global.intLogf(lvl, first, args...) - return errors.New(fmt.Sprintf(first, args...)) + return fmt.Errorf(first, args...) case func() string: // Log the closure (no other arguments used) str := first() @@ -253,7 +252,6 @@ func Error(arg0 interface{}, args ...interface{}) error { Global.intLogf(lvl, fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...) return errors.New(fmt.Sprint(first) + fmt.Sprintf(strings.Repeat(" %v", len(args)), args...)) } - return nil } // Utility for critical log messages (returns an error for easy function returns) (see Debug() for parameter explanation) @@ -267,7 +265,7 @@ func Critical(arg0 interface{}, args ...interface{}) error { case string: // Use the string as a format string Global.intLogf(lvl, first, args...) - return errors.New(fmt.Sprintf(first, args...)) + return fmt.Errorf(first, args...) case func() string: // Log the closure (no other arguments used) str := first() @@ -278,5 +276,4 @@ func Critical(arg0 interface{}, args ...interface{}) error { Global.intLogf(lvl, fmt.Sprint(first)+strings.Repeat(" %v", len(args)), args...) return errors.New(fmt.Sprint(first) + fmt.Sprintf(strings.Repeat(" %v", len(args)), args...)) } - return nil }