From 30bb530903352039c1b5055a756b7e246e2406b6 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Mon, 11 Jan 2016 09:13:38 -0600 Subject: [PATCH] Upgrading logging package --- Godeps/Godeps.json | 5 +- .../src/code.google.com/p/log4go/.hgtags | 4 - .../code.google.com/p/log4go/log4go_test.go | 534 ------------------ .../src/code.google.com/p/log4go/termlog.go | 45 -- .../github.com/alecthomas/log4go/.gitignore | 2 + .../alecthomas}/log4go/LICENSE | 0 .../p => github.com/alecthomas}/log4go/README | 0 .../alecthomas}/log4go/config.go | 4 +- .../examples/ConsoleLogWriter_Manual.go | 1 + .../log4go/examples/FileLogWriter_Manual.go | 0 .../log4go/examples/SimpleNetLogServer.go | 0 .../log4go/examples/SocketLogWriter_Manual.go | 0 .../examples/XMLConfigurationExample.go | 0 .../alecthomas}/log4go/examples/example.xml | 0 .../alecthomas}/log4go/filelog.go | 53 +- .../alecthomas}/log4go/log4go.go | 32 +- .../alecthomas}/log4go/pattlog.go | 8 +- .../alecthomas}/log4go/socklog.go | 0 .../github.com/alecthomas/log4go/termlog.go | 49 ++ .../alecthomas}/log4go/wrapper.go | 10 +- 20 files changed, 122 insertions(+), 625 deletions(-) delete mode 100644 Godeps/_workspace/src/code.google.com/p/log4go/.hgtags delete mode 100644 Godeps/_workspace/src/code.google.com/p/log4go/log4go_test.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/log4go/termlog.go create mode 100644 Godeps/_workspace/src/github.com/alecthomas/log4go/.gitignore rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/LICENSE (100%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/README (100%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/config.go (99%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/examples/ConsoleLogWriter_Manual.go (93%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/examples/FileLogWriter_Manual.go (100%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/examples/SimpleNetLogServer.go (100%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/examples/SocketLogWriter_Manual.go (100%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/examples/XMLConfigurationExample.go (100%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/examples/example.xml (100%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/filelog.go (83%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/log4go.go (95%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/pattlog.go (94%) rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/socklog.go (100%) create mode 100644 Godeps/_workspace/src/github.com/alecthomas/log4go/termlog.go rename Godeps/_workspace/src/{code.google.com/p => github.com/alecthomas}/log4go/wrapper.go (97%) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index bd2392f90e..d9c4a61bdd 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -3,9 +3,8 @@ "GoVersion": "go1.5.1", "Deps": [ { - "ImportPath": "code.google.com/p/log4go", - "Comment": "go.weekly.2012-02-22-1", - "Rev": "c3294304d93f48a37d3bed1d382882a9c2989f99" + "ImportPath": "github.com/alecthomas/log4go", + "Rev": "8e9057c3b25c409a34c0b9737cdc82cbcafeabce" }, { "ImportPath": "github.com/braintree/manners", diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/.hgtags b/Godeps/_workspace/src/code.google.com/p/log4go/.hgtags deleted file mode 100644 index 72a2eea2cc..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/log4go/.hgtags +++ /dev/null @@ -1,4 +0,0 @@ -4fbe6aadba231e838a449d340e43bdaab0bf85bd go.weekly.2012-02-07 -56168fd53249d639c25c74ced881fffb20d27be9 go.weekly.2012-02-22 -56168fd53249d639c25c74ced881fffb20d27be9 go.weekly.2012-02-22 -5c22fbd77d91f54d76cdbdee05318699754c44cc go.weekly.2012-02-22 diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/log4go_test.go b/Godeps/_workspace/src/code.google.com/p/log4go/log4go_test.go deleted file mode 100644 index 90c629977e..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/log4go/log4go_test.go +++ /dev/null @@ -1,534 +0,0 @@ -// Copyright (C) 2010, Kyle Lemons . All rights reserved. - -package log4go - -import ( - "crypto/md5" - "encoding/hex" - "fmt" - "io" - "io/ioutil" - "os" - "runtime" - "testing" - "time" -) - -const testLogFile = "_logtest.log" - -var now time.Time = time.Unix(0, 1234567890123456789).In(time.UTC) - -func newLogRecord(lvl level, src string, msg string) *LogRecord { - return &LogRecord{ - Level: lvl, - Source: src, - Created: now, - Message: msg, - } -} - -func TestELog(t *testing.T) { - fmt.Printf("Testing %s\n", L4G_VERSION) - lr := newLogRecord(CRITICAL, "source", "message") - if lr.Level != CRITICAL { - t.Errorf("Incorrect level: %d should be %d", lr.Level, CRITICAL) - } - if lr.Source != "source" { - t.Errorf("Incorrect source: %s should be %s", lr.Source, "source") - } - if lr.Message != "message" { - t.Errorf("Incorrect message: %s should be %s", lr.Source, "message") - } -} - -var formatTests = []struct { - Test string - Record *LogRecord - Formats map[string]string -}{ - { - Test: "Standard formats", - Record: &LogRecord{ - Level: ERROR, - Source: "source", - Message: "message", - Created: now, - }, - Formats: map[string]string{ - // TODO(kevlar): How can I do this so it'll work outside of PST? - FORMAT_DEFAULT: "[2009/02/13 23:31:30 UTC] [EROR] (source) message\n", - FORMAT_SHORT: "[23:31 02/13/09] [EROR] message\n", - FORMAT_ABBREV: "[EROR] message\n", - }, - }, -} - -func TestFormatLogRecord(t *testing.T) { - for _, test := range formatTests { - name := test.Test - for fmt, want := range test.Formats { - if got := FormatLogRecord(fmt, test.Record); got != want { - t.Errorf("%s - %s:", name, fmt) - t.Errorf(" got %q", got) - t.Errorf(" want %q", want) - } - } - } -} - -var logRecordWriteTests = []struct { - Test string - Record *LogRecord - Console string -}{ - { - Test: "Normal message", - Record: &LogRecord{ - Level: CRITICAL, - Source: "source", - Message: "message", - Created: now, - }, - Console: "[02/13/09 23:31:30] [CRIT] message\n", - }, -} - -func TestConsoleLogWriter(t *testing.T) { - console := make(ConsoleLogWriter) - - r, w := io.Pipe() - go console.run(w) - defer console.Close() - - buf := make([]byte, 1024) - - for _, test := range logRecordWriteTests { - name := test.Test - - 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) - } - } -} - -func TestFileLogWriter(t *testing.T) { - defer func(buflen int) { - LogBufferLength = buflen - }(LogBufferLength) - LogBufferLength = 0 - - w := NewFileLogWriter(testLogFile, false) - if w == nil { - t.Fatalf("Invalid return: w should not be nil") - } - defer os.Remove(testLogFile) - - w.LogWrite(newLogRecord(CRITICAL, "source", "message")) - w.Close() - runtime.Gosched() - - if contents, err := ioutil.ReadFile(testLogFile); err != nil { - t.Errorf("read(%q): %s", testLogFile, err) - } else if len(contents) != 50 { - t.Errorf("malformed filelog: %q (%d bytes)", string(contents), len(contents)) - } -} - -func TestXMLLogWriter(t *testing.T) { - defer func(buflen int) { - LogBufferLength = buflen - }(LogBufferLength) - LogBufferLength = 0 - - w := NewXMLLogWriter(testLogFile, false) - if w == nil { - t.Fatalf("Invalid return: w should not be nil") - } - defer os.Remove(testLogFile) - - w.LogWrite(newLogRecord(CRITICAL, "source", "message")) - w.Close() - runtime.Gosched() - - if contents, err := ioutil.ReadFile(testLogFile); err != nil { - t.Errorf("read(%q): %s", testLogFile, err) - } else if len(contents) != 185 { - t.Errorf("malformed xmllog: %q (%d bytes)", string(contents), len(contents)) - } -} - -func TestLogger(t *testing.T) { - sl := NewDefaultLogger(WARNING) - if sl == nil { - t.Fatalf("NewDefaultLogger should never return nil") - } - if lw, exist := sl["stdout"]; lw == nil || exist != true { - t.Fatalf("NewDefaultLogger produced invalid logger (DNE or nil)") - } - if sl["stdout"].Level != WARNING { - t.Fatalf("NewDefaultLogger produced invalid logger (incorrect level)") - } - if len(sl) != 1 { - t.Fatalf("NewDefaultLogger produced invalid logger (incorrect map count)") - } - - //func (l *Logger) AddFilter(name string, level int, writer LogWriter) {} - l := make(Logger) - l.AddFilter("stdout", DEBUG, NewConsoleLogWriter()) - if lw, exist := l["stdout"]; lw == nil || exist != true { - t.Fatalf("AddFilter produced invalid logger (DNE or nil)") - } - if l["stdout"].Level != DEBUG { - t.Fatalf("AddFilter produced invalid logger (incorrect level)") - } - if len(l) != 1 { - t.Fatalf("AddFilter produced invalid logger (incorrect map count)") - } - - //func (l *Logger) Warn(format string, args ...interface{}) error {} - if err := l.Warn("%s %d %#v", "Warning:", 1, []int{}); err.Error() != "Warning: 1 []int{}" { - t.Errorf("Warn returned invalid error: %s", err) - } - - //func (l *Logger) Error(format string, args ...interface{}) error {} - if err := l.Error("%s %d %#v", "Error:", 10, []string{}); err.Error() != "Error: 10 []string{}" { - t.Errorf("Error returned invalid error: %s", err) - } - - //func (l *Logger) Critical(format string, args ...interface{}) error {} - if err := l.Critical("%s %d %#v", "Critical:", 100, []int64{}); err.Error() != "Critical: 100 []int64{}" { - t.Errorf("Critical returned invalid error: %s", err) - } - - // Already tested or basically untestable - //func (l *Logger) Log(level int, source, message string) {} - //func (l *Logger) Logf(level int, format string, args ...interface{}) {} - //func (l *Logger) intLogf(level int, format string, args ...interface{}) string {} - //func (l *Logger) Finest(format string, args ...interface{}) {} - //func (l *Logger) Fine(format string, args ...interface{}) {} - //func (l *Logger) Debug(format string, args ...interface{}) {} - //func (l *Logger) Trace(format string, args ...interface{}) {} - //func (l *Logger) Info(format string, args ...interface{}) {} -} - -func TestLogOutput(t *testing.T) { - const ( - expected = "fdf3e51e444da56b4cb400f30bc47424" - ) - - // Unbuffered output - defer func(buflen int) { - LogBufferLength = buflen - }(LogBufferLength) - LogBufferLength = 0 - - 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")) - defer os.Remove(testLogFile) - - // Send some log messages - l.Log(CRITICAL, "testsrc1", fmt.Sprintf("This message is level %d", int(CRITICAL))) - l.Logf(ERROR, "This message is level %v", ERROR) - l.Logf(WARNING, "This message is level %s", WARNING) - l.Logc(INFO, func() string { return "This message is level INFO" }) - l.Trace("This message is level %d", int(TRACE)) - l.Debug("This message is level %s", DEBUG) - l.Fine(func() string { return fmt.Sprintf("This message is level %v", FINE) }) - l.Finest("This message is level %v", FINEST) - l.Finest(FINEST, "is also this message's level") - - l.Close() - - contents, err := ioutil.ReadFile(testLogFile) - if err != nil { - t.Fatalf("Could not read output log: %s", err) - } - - sum := md5.New() - sum.Write(contents) - if sumstr := hex.EncodeToString(sum.Sum(nil)); sumstr != expected { - t.Errorf("--- Log Contents:\n%s---", string(contents)) - t.Fatalf("Checksum does not match: %s (expecting %s)", sumstr, expected) - } -} - -func TestCountMallocs(t *testing.T) { - const N = 1 - var m runtime.MemStats - getMallocs := func() uint64 { - runtime.ReadMemStats(&m) - return m.Mallocs - } - - // Console logger - sl := NewDefaultLogger(INFO) - mallocs := 0 - getMallocs() - for i := 0; i < N; i++ { - sl.Log(WARNING, "here", "This is a WARNING message") - } - mallocs += getMallocs() - fmt.Printf("mallocs per sl.Log((WARNING, \"here\", \"This is a log message\"): %d\n", mallocs/N) - - // Console logger formatted - mallocs = 0 - getMallocs() - for i := 0; i < N; i++ { - sl.Logf(WARNING, "%s is a log message with level %d", "This", WARNING) - } - mallocs += getMallocs() - fmt.Printf("mallocs per sl.Logf(WARNING, \"%%s is a log message with level %%d\", \"This\", WARNING): %d\n", mallocs/N) - - // Console logger (not logged) - sl = NewDefaultLogger(INFO) - mallocs = 0 - getMallocs() - for i := 0; i < N; i++ { - sl.Log(DEBUG, "here", "This is a DEBUG log message") - } - mallocs += getMallocs() - fmt.Printf("mallocs per unlogged sl.Log((WARNING, \"here\", \"This is a log message\"): %d\n", mallocs/N) - - // Console logger formatted (not logged) - mallocs = 0 - getMallocs() - for i := 0; i < N; i++ { - sl.Logf(DEBUG, "%s is a log message with level %d", "This", DEBUG) - } - mallocs += getMallocs() - fmt.Printf("mallocs per unlogged sl.Logf(WARNING, \"%%s is a log message with level %%d\", \"This\", WARNING): %d\n", mallocs/N) -} - -func TestXMLConfig(t *testing.T) { - const ( - configfile = "example.xml" - ) - - fd, err := os.Create(configfile) - if err != nil { - 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, "") - fd.Close() - - log := make(Logger) - log.LoadConfiguration(configfile) - defer os.Remove("trace.xml") - defer os.Remove("test.log") - defer log.Close() - - // Make sure we got all loggers - if len(log) != 3 { - t.Fatalf("XMLConfig: Expected 3 filters, found %d", len(log)) - } - - // Make sure they're the right keys - if _, ok := log["stdout"]; !ok { - t.Errorf("XMLConfig: Expected stdout logger") - } - if _, ok := log["file"]; !ok { - t.Fatalf("XMLConfig: Expected file logger") - } - if _, ok := log["xmllog"]; !ok { - t.Fatalf("XMLConfig: Expected xmllog logger") - } - - // Make sure they're the right type - if _, ok := log["stdout"].LogWriter.(ConsoleLogWriter); !ok { - t.Fatalf("XMLConfig: Expected stdout to be ConsoleLogWriter, found %T", log["stdout"].LogWriter) - } - if _, ok := log["file"].LogWriter.(*FileLogWriter); !ok { - t.Fatalf("XMLConfig: Expected file to be *FileLogWriter, found %T", log["file"].LogWriter) - } - if _, ok := log["xmllog"].LogWriter.(*FileLogWriter); !ok { - t.Fatalf("XMLConfig: Expected xmllog to be *FileLogWriter, found %T", log["xmllog"].LogWriter) - } - - // Make sure levels are set - if lvl := log["stdout"].Level; lvl != DEBUG { - t.Errorf("XMLConfig: Expected stdout to be set to level %d, found %d", DEBUG, lvl) - } - if lvl := log["file"].Level; lvl != FINEST { - t.Errorf("XMLConfig: Expected file to be set to level %d, found %d", FINEST, lvl) - } - if lvl := log["xmllog"].Level; lvl != TRACE { - t.Errorf("XMLConfig: Expected xmllog to be set to level %d, found %d", TRACE, lvl) - } - - // Make sure the w is open and points to the right file - if fname := log["file"].LogWriter.(*FileLogWriter).file.Name(); fname != "test.log" { - t.Errorf("XMLConfig: Expected file to have opened %s, found %s", "test.log", fname) - } - - // Make sure the XLW is open and points to the right file - if fname := log["xmllog"].LogWriter.(*FileLogWriter).file.Name(); fname != "trace.xml" { - t.Errorf("XMLConfig: Expected xmllog to have opened %s, found %s", "trace.xml", fname) - } - - // Move XML log file - os.Rename(configfile, "examples/"+configfile) // Keep this so that an example with the documentation is available -} - -func BenchmarkFormatLogRecord(b *testing.B) { - const updateEvery = 1 - rec := &LogRecord{ - Level: CRITICAL, - Created: now, - Source: "source", - Message: "message", - } - for i := 0; i < b.N; i++ { - rec.Created = rec.Created.Add(1 * time.Second / updateEvery) - if i%2 == 0 { - FormatLogRecord(FORMAT_DEFAULT, rec) - } else { - FormatLogRecord(FORMAT_SHORT, rec) - } - } -} - -func BenchmarkConsoleLog(b *testing.B) { - /* This doesn't seem to work on OS X - sink, err := os.Open(os.DevNull) - if err != nil { - panic(err) - } - if err := syscall.Dup2(int(sink.Fd()), syscall.Stdout); err != nil { - panic(err) - } - */ - - stdout = ioutil.Discard - sl := NewDefaultLogger(INFO) - for i := 0; i < b.N; i++ { - sl.Log(WARNING, "here", "This is a log message") - } -} - -func BenchmarkConsoleNotLogged(b *testing.B) { - sl := NewDefaultLogger(INFO) - for i := 0; i < b.N; i++ { - sl.Log(DEBUG, "here", "This is a log message") - } -} - -func BenchmarkConsoleUtilLog(b *testing.B) { - sl := NewDefaultLogger(INFO) - for i := 0; i < b.N; i++ { - sl.Info("%s is a log message", "This") - } -} - -func BenchmarkConsoleUtilNotLog(b *testing.B) { - sl := NewDefaultLogger(INFO) - for i := 0; i < b.N; i++ { - sl.Debug("%s is a log message", "This") - } -} - -func BenchmarkFileLog(b *testing.B) { - sl := make(Logger) - b.StopTimer() - sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false)) - b.StartTimer() - for i := 0; i < b.N; i++ { - sl.Log(WARNING, "here", "This is a log message") - } - b.StopTimer() - os.Remove("benchlog.log") -} - -func BenchmarkFileNotLogged(b *testing.B) { - sl := make(Logger) - b.StopTimer() - sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false)) - b.StartTimer() - for i := 0; i < b.N; i++ { - sl.Log(DEBUG, "here", "This is a log message") - } - b.StopTimer() - os.Remove("benchlog.log") -} - -func BenchmarkFileUtilLog(b *testing.B) { - sl := make(Logger) - b.StopTimer() - sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false)) - b.StartTimer() - for i := 0; i < b.N; i++ { - sl.Info("%s is a log message", "This") - } - b.StopTimer() - os.Remove("benchlog.log") -} - -func BenchmarkFileUtilNotLog(b *testing.B) { - sl := make(Logger) - b.StopTimer() - sl.AddFilter("file", INFO, NewFileLogWriter("benchlog.log", false)) - b.StartTimer() - for i := 0; i < b.N; i++ { - sl.Debug("%s is a log message", "This") - } - b.StopTimer() - os.Remove("benchlog.log") -} - -// Benchmark results (darwin amd64 6g) -//elog.BenchmarkConsoleLog 100000 22819 ns/op -//elog.BenchmarkConsoleNotLogged 2000000 879 ns/op -//elog.BenchmarkConsoleUtilLog 50000 34380 ns/op -//elog.BenchmarkConsoleUtilNotLog 1000000 1339 ns/op -//elog.BenchmarkFileLog 100000 26497 ns/op -//elog.BenchmarkFileNotLogged 2000000 821 ns/op -//elog.BenchmarkFileUtilLog 50000 33945 ns/op -//elog.BenchmarkFileUtilNotLog 1000000 1258 ns/op diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/termlog.go b/Godeps/_workspace/src/code.google.com/p/log4go/termlog.go deleted file mode 100644 index 1ed2e4e0de..0000000000 --- a/Godeps/_workspace/src/code.google.com/p/log4go/termlog.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2010, Kyle Lemons . All rights reserved. - -package log4go - -import ( - "io" - "os" - "fmt" -) - -var stdout io.Writer = os.Stdout - -// This is the standard writer that prints to standard output. -type ConsoleLogWriter chan *LogRecord - -// This creates a new ConsoleLogWriter -func NewConsoleLogWriter() ConsoleLogWriter { - records := make(ConsoleLogWriter, LogBufferLength) - go records.run(stdout) - return records -} - -func (w ConsoleLogWriter) run(out io.Writer) { - var timestr string - var timestrAt int64 - - for rec := range w { - if at := rec.Created.UnixNano() / 1e9; at != timestrAt { - timestr, timestrAt = rec.Created.Format("01/02/06 15:04:05"), at - } - fmt.Fprint(out, "[", timestr, "] [", levelStrings[rec.Level], "] ", rec.Message, "\n") - } -} - -// This is the ConsoleLogWriter's output method. This will block if the output -// buffer is full. -func (w ConsoleLogWriter) LogWrite(rec *LogRecord) { - w <- rec -} - -// Close stops the logger from sending messages to standard output. Attempts to -// send log messages to this logger after a Close have undefined behavior. -func (w ConsoleLogWriter) Close() { - close(w) -} diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/.gitignore b/Godeps/_workspace/src/github.com/alecthomas/log4go/.gitignore new file mode 100644 index 0000000000..f6207cd8a2 --- /dev/null +++ b/Godeps/_workspace/src/github.com/alecthomas/log4go/.gitignore @@ -0,0 +1,2 @@ +*.sw[op] +.DS_Store diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/LICENSE b/Godeps/_workspace/src/github.com/alecthomas/log4go/LICENSE similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/log4go/LICENSE rename to Godeps/_workspace/src/github.com/alecthomas/log4go/LICENSE diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/README b/Godeps/_workspace/src/github.com/alecthomas/log4go/README similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/log4go/README rename to Godeps/_workspace/src/github.com/alecthomas/log4go/README diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/config.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/config.go similarity index 99% rename from Godeps/_workspace/src/code.google.com/p/log4go/config.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/config.go index f048b69f56..577c3eb2f8 100644 --- a/Godeps/_workspace/src/code.google.com/p/log4go/config.go +++ b/Godeps/_workspace/src/github.com/alecthomas/log4go/config.go @@ -53,7 +53,7 @@ func (log Logger) LoadConfiguration(filename string) { for _, xmlfilt := range xc.Filter { var filt LogWriter - var lvl level + var lvl Level bad, good, enabled := false, true, false // Check required children @@ -131,7 +131,7 @@ func (log Logger) LoadConfiguration(filename string) { } } -func xmlToConsoleLogWriter(filename string, props []xmlProperty, enabled bool) (ConsoleLogWriter, bool) { +func xmlToConsoleLogWriter(filename string, props []xmlProperty, enabled bool) (*ConsoleLogWriter, bool) { // Parse properties for _, prop := range props { switch prop.Name { diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/examples/ConsoleLogWriter_Manual.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/ConsoleLogWriter_Manual.go similarity index 93% rename from Godeps/_workspace/src/code.google.com/p/log4go/examples/ConsoleLogWriter_Manual.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/examples/ConsoleLogWriter_Manual.go index 394ca83806..698dd332d8 100644 --- a/Godeps/_workspace/src/code.google.com/p/log4go/examples/ConsoleLogWriter_Manual.go +++ b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/ConsoleLogWriter_Manual.go @@ -8,6 +8,7 @@ import l4g "code.google.com/p/log4go" func main() { log := l4g.NewLogger() + defer log.Close() log.AddFilter("stdout", l4g.DEBUG, l4g.NewConsoleLogWriter()) log.Info("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02")) } diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/examples/FileLogWriter_Manual.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/FileLogWriter_Manual.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/log4go/examples/FileLogWriter_Manual.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/examples/FileLogWriter_Manual.go diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/examples/SimpleNetLogServer.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SimpleNetLogServer.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/log4go/examples/SimpleNetLogServer.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SimpleNetLogServer.go diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/examples/SocketLogWriter_Manual.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SocketLogWriter_Manual.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/log4go/examples/SocketLogWriter_Manual.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/examples/SocketLogWriter_Manual.go diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/examples/XMLConfigurationExample.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/XMLConfigurationExample.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/log4go/examples/XMLConfigurationExample.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/examples/XMLConfigurationExample.go diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/examples/example.xml b/Godeps/_workspace/src/github.com/alecthomas/log4go/examples/example.xml similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/log4go/examples/example.xml rename to Godeps/_workspace/src/github.com/alecthomas/log4go/examples/example.xml diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/filelog.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/filelog.go similarity index 83% rename from Godeps/_workspace/src/code.google.com/p/log4go/filelog.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/filelog.go index 9cbd815d99..ee0ab0c046 100644 --- a/Godeps/_workspace/src/code.google.com/p/log4go/filelog.go +++ b/Godeps/_workspace/src/github.com/alecthomas/log4go/filelog.go @@ -3,8 +3,8 @@ package log4go import ( - "os" "fmt" + "os" "time" ) @@ -36,7 +36,8 @@ type FileLogWriter struct { daily_opendate int // Keep old logfiles (.001, .002, etc) - rotate bool + rotate bool + maxbackup int } // This is the FileLogWriter's output method @@ -46,6 +47,7 @@ func (w *FileLogWriter) LogWrite(rec *LogRecord) { func (w *FileLogWriter) Close() { close(w.rec) + w.file.Sync() } // NewFileLogWriter creates a new LogWriter which writes to the given file and @@ -59,11 +61,12 @@ func (w *FileLogWriter) Close() { // [%D %T] [%L] (%S) %M func NewFileLogWriter(fname string, rotate bool) *FileLogWriter { w := &FileLogWriter{ - rec: make(chan *LogRecord, LogBufferLength), - rot: make(chan bool), - filename: fname, - format: "[%D %T] [%L] (%S) %M", - rotate: rotate, + rec: make(chan *LogRecord, LogBufferLength), + rot: make(chan bool), + filename: fname, + format: "[%D %T] [%L] (%S) %M", + rotate: rotate, + maxbackup: 999, } // open the file for the first time @@ -138,15 +141,30 @@ func (w *FileLogWriter) intRotate() error { // Find the next available number num := 1 fname := "" - for ; err == nil && num <= 999; num++ { - fname = w.filename + fmt.Sprintf(".%03d", num) - _, err = os.Lstat(fname) - } - // return error if the last file checked still existed - if err == nil { - return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename) + if w.daily && time.Now().Day() != w.daily_opendate { + yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02") + + for ; err == nil && num <= 999; num++ { + fname = w.filename + fmt.Sprintf(".%s.%03d", yesterday, num) + _, err = os.Lstat(fname) + } + // return error if the last file checked still existed + if err == nil { + return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename) + } + } else { + num = w.maxbackup - 1 + for ; num >= 1; num-- { + fname = w.filename + fmt.Sprintf(".%d", num) + nfname := w.filename + fmt.Sprintf(".%d", num+1) + _, err = os.Lstat(fname) + if err == nil { + os.Rename(fname, nfname) + } + } } + w.file.Close() // Rename the file to its newfound home err = os.Rename(w.filename, fname) if err != nil { @@ -217,6 +235,13 @@ func (w *FileLogWriter) SetRotateDaily(daily bool) *FileLogWriter { return w } +// Set max backup files. Must be called before the first log message +// is written. +func (w *FileLogWriter) SetRotateMaxBackup(maxbackup int) *FileLogWriter { + w.maxbackup = maxbackup + return w +} + // SetRotate changes whether or not the old logs are kept. (chainable) Must be // called before the first log message is written. If rotate is false, the // files are overwritten; otherwise, they are rotated to another file before the diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/log4go.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/log4go.go similarity index 95% rename from Godeps/_workspace/src/code.google.com/p/log4go/log4go.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/log4go.go index ab4e857f51..822e890ccb 100644 --- a/Godeps/_workspace/src/code.google.com/p/log4go/log4go.go +++ b/Godeps/_workspace/src/github.com/alecthomas/log4go/log4go.go @@ -47,11 +47,11 @@ package log4go import ( "errors" - "os" "fmt" - "time" - "strings" + "os" "runtime" + "strings" + "time" ) // Version information @@ -65,10 +65,10 @@ const ( /****** Constants ******/ // These are the integer logging levels used by the logger -type level int +type Level int const ( - FINEST level = iota + FINEST Level = iota FINE DEBUG TRACE @@ -83,7 +83,7 @@ var ( levelStrings = [...]string{"FNST", "FINE", "DEBG", "TRAC", "INFO", "WARN", "EROR", "CRIT"} ) -func (l level) String() string { +func (l Level) String() string { if l < 0 || int(l) > len(levelStrings) { return "UNKNOWN" } @@ -101,7 +101,7 @@ var ( // A LogRecord contains all of the pertinent information for each message type LogRecord struct { - Level level // The log level + Level Level // The log level Created time.Time // The time at which the log message was created (nanoseconds) Source string // The message source Message string // The log message @@ -124,7 +124,7 @@ type LogWriter interface { // A Filter represents the log level below which no log records are written to // the associated LogWriter. type Filter struct { - Level level + Level Level LogWriter } @@ -144,7 +144,7 @@ func NewLogger() Logger { // or above lvl to standard output. // // DEPRECATED: use NewDefaultLogger instead. -func NewConsoleLogger(lvl level) Logger { +func NewConsoleLogger(lvl Level) Logger { os.Stderr.WriteString("warning: use of deprecated NewConsoleLogger\n") return Logger{ "stdout": &Filter{lvl, NewConsoleLogWriter()}, @@ -153,7 +153,7 @@ func NewConsoleLogger(lvl level) Logger { // Create a new logger with a "stdout" filter configured to send log messages at // or above lvl to standard output. -func NewDefaultLogger(lvl level) Logger { +func NewDefaultLogger(lvl Level) Logger { return Logger{ "stdout": &Filter{lvl, NewConsoleLogWriter()}, } @@ -174,14 +174,14 @@ func (log Logger) Close() { // Add a new LogWriter to the Logger which will only log messages at lvl or // higher. This function should not be called from multiple goroutines. // Returns the logger for chaining. -func (log Logger) AddFilter(name string, lvl level, writer LogWriter) Logger { +func (log Logger) AddFilter(name string, lvl Level, writer LogWriter) Logger { log[name] = &Filter{lvl, writer} return log } /******* Logging *******/ // Send a formatted log message internally -func (log Logger) intLogf(lvl level, format string, args ...interface{}) { +func (log Logger) intLogf(lvl Level, format string, args ...interface{}) { skip := true // Determine if any logging will be done @@ -225,7 +225,7 @@ func (log Logger) intLogf(lvl level, format string, args ...interface{}) { } // Send a closure log message internally -func (log Logger) intLogc(lvl level, closure func() string) { +func (log Logger) intLogc(lvl Level, closure func() string) { skip := true // Determine if any logging will be done @@ -264,7 +264,7 @@ func (log Logger) intLogc(lvl level, closure func() string) { } // Send a log message with manual level, source, and message. -func (log Logger) Log(lvl level, source, message string) { +func (log Logger) Log(lvl Level, source, message string) { skip := true // Determine if any logging will be done @@ -297,13 +297,13 @@ func (log Logger) Log(lvl level, source, message string) { // Logf logs a formatted log message at the given log level, using the caller as // its source. -func (log Logger) Logf(lvl level, format string, args ...interface{}) { +func (log Logger) Logf(lvl Level, format string, args ...interface{}) { log.intLogf(lvl, format, args...) } // Logc logs a string returned by the closure at the given log level, using the caller as // its source. If no log message would be written, the closure is never called. -func (log Logger) Logc(lvl level, closure func() string) { +func (log Logger) Logc(lvl Level, closure func() string) { log.intLogc(lvl, closure) } diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/pattlog.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/pattlog.go similarity index 94% rename from Godeps/_workspace/src/code.google.com/p/log4go/pattlog.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/pattlog.go index 8224302b36..82b4e36b1f 100644 --- a/Godeps/_workspace/src/code.google.com/p/log4go/pattlog.go +++ b/Godeps/_workspace/src/github.com/alecthomas/log4go/pattlog.go @@ -3,9 +3,10 @@ package log4go import ( - "fmt" "bytes" + "fmt" "io" + "strings" ) const ( @@ -51,7 +52,7 @@ func FormatLogRecord(format string, rec *LogRecord) string { updated := &formatCacheType{ LastUpdateSeconds: secs, shortTime: fmt.Sprintf("%02d:%02d", hour, minute), - shortDate: fmt.Sprintf("%02d/%02d/%02d", month, day, year%100), + shortDate: fmt.Sprintf("%02d/%02d/%02d", day, month, year%100), longTime: fmt.Sprintf("%02d:%02d:%02d %s", hour, minute, second, zone), longDate: fmt.Sprintf("%04d/%02d/%02d", year, month, day), } @@ -78,6 +79,9 @@ func FormatLogRecord(format string, rec *LogRecord) string { out.WriteString(levelStrings[rec.Level]) case 'S': out.WriteString(rec.Source) + case 's': + slice := strings.Split(rec.Source, "/") + out.WriteString(slice[len(slice)-1]) case 'M': out.WriteString(rec.Message) } diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/socklog.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/socklog.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/log4go/socklog.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/socklog.go diff --git a/Godeps/_workspace/src/github.com/alecthomas/log4go/termlog.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/termlog.go new file mode 100644 index 0000000000..8a941e2698 --- /dev/null +++ b/Godeps/_workspace/src/github.com/alecthomas/log4go/termlog.go @@ -0,0 +1,49 @@ +// Copyright (C) 2010, Kyle Lemons . All rights reserved. + +package log4go + +import ( + "fmt" + "io" + "os" + "time" +) + +var stdout io.Writer = os.Stdout + +// This is the standard writer that prints to standard output. +type ConsoleLogWriter struct { + format string + w chan *LogRecord +} + +// This creates a new ConsoleLogWriter +func NewConsoleLogWriter() *ConsoleLogWriter { + consoleWriter := &ConsoleLogWriter{ + format: "[%T %D] [%L] (%S) %M", + w: make(chan *LogRecord, LogBufferLength), + } + go consoleWriter.run(stdout) + return consoleWriter +} +func (c *ConsoleLogWriter) SetFormat(format string) { + c.format = format +} +func (c *ConsoleLogWriter) run(out io.Writer) { + for rec := range c.w { + fmt.Fprint(out, FormatLogRecord(c.format, rec)) + } +} + +// This is the ConsoleLogWriter's output method. This will block if the output +// buffer is full. +func (c *ConsoleLogWriter) LogWrite(rec *LogRecord) { + c.w <- rec +} + +// Close stops the logger from sending messages to standard output. Attempts to +// send log messages to this logger after a Close have undefined behavior. +func (c *ConsoleLogWriter) Close() { + close(c.w) + time.Sleep(50 * time.Millisecond) // Try to give console I/O time to complete +} diff --git a/Godeps/_workspace/src/code.google.com/p/log4go/wrapper.go b/Godeps/_workspace/src/github.com/alecthomas/log4go/wrapper.go similarity index 97% rename from Godeps/_workspace/src/code.google.com/p/log4go/wrapper.go rename to Godeps/_workspace/src/github.com/alecthomas/log4go/wrapper.go index 10ecd88e6d..2ae222b0c4 100644 --- a/Godeps/_workspace/src/code.google.com/p/log4go/wrapper.go +++ b/Godeps/_workspace/src/github.com/alecthomas/log4go/wrapper.go @@ -4,8 +4,8 @@ package log4go import ( "errors" - "os" "fmt" + "os" "strings" ) @@ -23,7 +23,7 @@ func LoadConfiguration(filename string) { } // Wrapper for (*Logger).AddFilter -func AddFilter(name string, lvl level, writer LogWriter) { +func AddFilter(name string, lvl Level, writer LogWriter) { Global.AddFilter(name, lvl, writer) } @@ -88,19 +88,19 @@ func Stdoutf(format string, args ...interface{}) { // Send a log message manually // Wrapper for (*Logger).Log -func Log(lvl level, source, message string) { +func Log(lvl Level, source, message string) { Global.Log(lvl, source, message) } // Send a formatted log message easily // Wrapper for (*Logger).Logf -func Logf(lvl level, format string, args ...interface{}) { +func Logf(lvl Level, format string, args ...interface{}) { Global.intLogf(lvl, format, args...) } // Send a closure log message // Wrapper for (*Logger).Logc -func Logc(lvl level, closure func() string) { +func Logc(lvl Level, closure func() string) { Global.intLogc(lvl, closure) }