From a1cb00070123ffcdbd461d5b2946c0b7606ce50d Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 3 Feb 2016 14:42:38 +0800 Subject: [PATCH 01/14] remove log package --- logs/conn.go | 17 ++++++------- logs/console.go | 11 +++------ logs/file.go | 10 +++----- logs/log.go | 42 -------------------------------- logs/logger.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 65 deletions(-) create mode 100644 logs/logger.go diff --git a/logs/conn.go b/logs/conn.go index 5d78467b..1db1a427 100644 --- a/logs/conn.go +++ b/logs/conn.go @@ -17,7 +17,6 @@ package logs import ( "encoding/json" "io" - "log" "net" "time" ) @@ -25,7 +24,7 @@ import ( // connWriter implements LoggerInterface. // it writes messages in keep-live tcp connection. type connWriter struct { - lg *log.Logger + lg *logWriter innerWriter io.WriteCloser ReconnectOnMsg bool `json:"reconnectOnMsg"` Reconnect bool `json:"reconnect"` @@ -43,8 +42,8 @@ func NewConn() Logger { // Init init connection writer with json config. // json config only need key "level". -func (c *connWriter) Init(jsonconfig string) error { - return json.Unmarshal([]byte(jsonconfig), c) +func (c *connWriter) Init(jsonConfig string) error { + return json.Unmarshal([]byte(jsonConfig), c) } // WriteMsg write message in connection. @@ -53,7 +52,7 @@ func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error { if level > c.Level { return nil } - if c.neddedConnectOnMsg() { + if c.needToConnectOnMsg() { err := c.connect() if err != nil { return err @@ -64,9 +63,7 @@ func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error { defer c.innerWriter.Close() } - msg = formatLogTime(when) + msg - - c.lg.Println(msg) + c.lg.println(when, msg) return nil } @@ -98,11 +95,11 @@ func (c *connWriter) connect() error { } c.innerWriter = conn - c.lg = log.New(conn, "", 0) + c.lg = newLogWriter(conn) return nil } -func (c *connWriter) neddedConnectOnMsg() bool { +func (c *connWriter) needToConnectOnMsg() bool { if c.Reconnect { c.Reconnect = false return true diff --git a/logs/console.go b/logs/console.go index 3781e6cd..05d08a42 100644 --- a/logs/console.go +++ b/logs/console.go @@ -16,7 +16,6 @@ package logs import ( "encoding/json" - "log" "os" "runtime" "time" @@ -47,7 +46,7 @@ var colors = []brush{ // consoleWriter implements LoggerInterface and writes messages to terminal. type consoleWriter struct { - lg *log.Logger + lg *logWriter Level int `json:"level"` Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color } @@ -55,7 +54,7 @@ type consoleWriter struct { // NewConsole create ConsoleWriter returning as LoggerInterface. func NewConsole() Logger { cw := &consoleWriter{ - lg: log.New(os.Stdout, "", 0), + lg: newLogWriter(os.Stdout), Level: LevelDebug, Colorful: true, } @@ -80,12 +79,10 @@ func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error { if level > c.Level { return nil } - msg = formatLogTime(when) + msg if c.Colorful { - c.lg.Println(colors[level](msg)) - } else { - c.lg.Println(msg) + msg = colors[level](msg) } + c.lg.println(when, msg) return nil } diff --git a/logs/file.go b/logs/file.go index 3a042164..6001b982 100644 --- a/logs/file.go +++ b/logs/file.go @@ -118,13 +118,11 @@ func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error { if level > w.Level { return nil } - msg = formatLogTime(when) + msg + "\n" - + h, d := formatTimeHeader(when) if w.Rotate { - d := when.Day() - if w.needRotate(len(msg), d) { + if w.needRotate(len(h)+len(msg)+1, d) { w.Lock() - if w.needRotate(len(msg), d) { + if w.needRotate(len(h)+len(msg)+1, d) { if err := w.doRotate(when); err != nil { fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err) } @@ -134,7 +132,7 @@ func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error { } w.Lock() - _, err := w.fileWriter.Write([]byte(msg)) + _, err := w.fileWriter.Write(append(append(h, msg...), '\n')) if err == nil { w.maxLinesCurLines++ w.maxSizeCurSize += len(msg) diff --git a/logs/log.go b/logs/log.go index 2a12ed79..f53d2382 100644 --- a/logs/log.go +++ b/logs/log.go @@ -367,45 +367,3 @@ func (bl *BeeLogger) Close() { } bl.outputs = nil } - -func formatLogTime(when time.Time) string { - y, mo, d := when.Date() - h, mi, s := when.Clock() - //len(2006/01/02 15:03:04)==19 - var buf [20]byte - t := 3 - for y >= 10 { - p := y / 10 - buf[t] = byte('0' + y - p*10) - y = p - t-- - } - buf[0] = byte('0' + y) - buf[4] = '/' - if mo > 9 { - buf[5] = '1' - buf[6] = byte('0' + mo - 9) - } else { - buf[5] = '0' - buf[6] = byte('0' + mo) - } - buf[7] = '/' - t = d / 10 - buf[8] = byte('0' + t) - buf[9] = byte('0' + d - t*10) - buf[10] = ' ' - t = h / 10 - buf[11] = byte('0' + t) - buf[12] = byte('0' + h - t*10) - buf[13] = ':' - t = mi / 10 - buf[14] = byte('0' + t) - buf[15] = byte('0' + mi - t*10) - buf[16] = ':' - t = s / 10 - buf[17] = byte('0' + t) - buf[18] = byte('0' + s - t*10) - buf[19] = ' ' - - return string(buf[0:]) -} diff --git a/logs/logger.go b/logs/logger.go new file mode 100644 index 00000000..ffcead2b --- /dev/null +++ b/logs/logger.go @@ -0,0 +1,65 @@ +package logs + +import ( + "io" + "sync" + "time" +) + +type logWriter struct { + sync.Mutex + writer io.Writer +} + +func newLogWriter(wr io.Writer) *logWriter { + return &logWriter{writer: wr} +} + +func (lg *logWriter) println(when time.Time, msg string) { + lg.Lock() + h, _ := formatTimeHeader(when) + lg.writer.Write(append(append(h, msg...), '\n')) + lg.Unlock() +} + +func formatTimeHeader(when time.Time) ([]byte, int) { + y, mo, d := when.Date() + h, mi, s := when.Clock() + //len(2006/01/02 15:03:04)==19 + var buf [20]byte + t := 3 + for y >= 10 { + p := y / 10 + buf[t] = byte('0' + y - p*10) + y = p + t-- + } + buf[0] = byte('0' + y) + buf[4] = '/' + if mo > 9 { + buf[5] = '1' + buf[6] = byte('0' + mo - 9) + } else { + buf[5] = '0' + buf[6] = byte('0' + mo) + } + buf[7] = '/' + t = d / 10 + buf[8] = byte('0' + t) + buf[9] = byte('0' + d - t*10) + buf[10] = ' ' + t = h / 10 + buf[11] = byte('0' + t) + buf[12] = byte('0' + h - t*10) + buf[13] = ':' + t = mi / 10 + buf[14] = byte('0' + t) + buf[15] = byte('0' + mi - t*10) + buf[16] = ':' + t = s / 10 + buf[17] = byte('0' + t) + buf[18] = byte('0' + s - t*10) + buf[19] = ' ' + + return buf[0:], d +} From 9806a43783f240e0d15f8c2e2fdb92a718b3533c Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 3 Feb 2016 15:03:37 +0800 Subject: [PATCH 02/14] make more fast --- logs/file.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/logs/file.go b/logs/file.go index 6001b982..ae58fc29 100644 --- a/logs/file.go +++ b/logs/file.go @@ -119,10 +119,11 @@ func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error { return nil } h, d := formatTimeHeader(when) + msg = string(h) + msg + "\n" if w.Rotate { - if w.needRotate(len(h)+len(msg)+1, d) { + if w.needRotate(len(msg), d) { w.Lock() - if w.needRotate(len(h)+len(msg)+1, d) { + if w.needRotate(len(msg), d) { if err := w.doRotate(when); err != nil { fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err) } @@ -132,7 +133,7 @@ func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error { } w.Lock() - _, err := w.fileWriter.Write(append(append(h, msg...), '\n')) + _, err := w.fileWriter.Write([]byte(msg)) if err == nil { w.maxLinesCurLines++ w.maxSizeCurSize += len(msg) From 304a5ccea0945156f68a34b205718a97cabba7af Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 3 Feb 2016 15:06:53 +0800 Subject: [PATCH 03/14] comment fix --- logs/file.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/file.go b/logs/file.go index ae58fc29..5928d1c4 100644 --- a/logs/file.go +++ b/logs/file.go @@ -55,7 +55,7 @@ type fileLogWriter struct { Perm os.FileMode `json:"perm"` } -// NewFileWriter create a FileLogWriter returning as LoggerInterface. +// newFileWriter create a FileLogWriter returning as LoggerInterface. func newFileWriter() Logger { w := &fileLogWriter{ Filename: "", From 6caa3ecd91ce16b96d21982d951173c35531f348 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 3 Feb 2016 15:31:59 +0800 Subject: [PATCH 04/14] when rotate by date ,there's no num after log file --- logs/file.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/logs/file.go b/logs/file.go index 5928d1c4..6fa2935b 100644 --- a/logs/file.go +++ b/logs/file.go @@ -210,8 +210,13 @@ func (w *fileLogWriter) doRotate(logTime time.Time) error { if suffix == "" { suffix = ".log" } - for ; err == nil && num <= 999; num++ { - fName = filenameOnly + fmt.Sprintf(".%s.%03d%s", logTime.Format("2006-01-02"), num, suffix) + if w.MaxLines > 0 || w.MaxSize > 0 { + for ; err == nil && num <= 999; num++ { + fName = filenameOnly + fmt.Sprintf(".%s.%03d%s", logTime.Format("2006-01-02"), num, suffix) + _, err = os.Lstat(fName) + } + } else { + fName = fmt.Sprintf("%s.%s.%s", filenameOnly, logTime.Format("2006-01-02"), suffix) _, err = os.Lstat(fName) } // return error if the last file checked still existed From 68cc53e92b85e58664c0791ad89b436419f79330 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 3 Feb 2016 15:43:15 +0800 Subject: [PATCH 05/14] when rotate by date ,there's no num after log file --- logs/file.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/file.go b/logs/file.go index 6fa2935b..4f228267 100644 --- a/logs/file.go +++ b/logs/file.go @@ -195,7 +195,7 @@ func (w *fileLogWriter) lines() (int, error) { } // DoRotate means it need to write file in new file. -// new file name like xx.2013-01-01.2.log +// new file name like xx.2013-01-01.log (daily) or xx.001.log (by line or size) func (w *fileLogWriter) doRotate(logTime time.Time) error { _, err := os.Lstat(w.Filename) if err != nil { From 51b1095e73d46eb21d7bb8042285703e7038ec2b Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 3 Feb 2016 16:32:59 +0800 Subject: [PATCH 06/14] add files logger --- logs/file.go | 16 +++++++------ logs/files.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ logs/log.go | 4 +++- 3 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 logs/files.go diff --git a/logs/file.go b/logs/file.go index 4f228267..990a76d8 100644 --- a/logs/file.go +++ b/logs/file.go @@ -53,6 +53,8 @@ type fileLogWriter struct { Level int `json:"level"` Perm os.FileMode `json:"perm"` + + fileNameOnly, suffix string // like "project.log", project is fileNameOnly and .log is suffix } // newFileWriter create a FileLogWriter returning as LoggerInterface. @@ -89,6 +91,11 @@ func (w *fileLogWriter) Init(jsonConfig string) error { if len(w.Filename) == 0 { return errors.New("jsonconfig must have filename") } + w.suffix = filepath.Ext(w.Filename) + w.fileNameOnly = strings.TrimSuffix(w.Filename, w.suffix) + if w.suffix == "" { + w.suffix = ".log" + } err = w.startLogger() return err } @@ -205,18 +212,13 @@ func (w *fileLogWriter) doRotate(logTime time.Time) error { // Find the next available number num := 1 fName := "" - suffix := filepath.Ext(w.Filename) - filenameOnly := strings.TrimSuffix(w.Filename, suffix) - if suffix == "" { - suffix = ".log" - } if w.MaxLines > 0 || w.MaxSize > 0 { for ; err == nil && num <= 999; num++ { - fName = filenameOnly + fmt.Sprintf(".%s.%03d%s", logTime.Format("2006-01-02"), num, suffix) + fName = w.fileNameOnly + fmt.Sprintf(".%s.%03d%s", logTime.Format("2006-01-02"), num, w.suffix) _, err = os.Lstat(fName) } } else { - fName = fmt.Sprintf("%s.%s.%s", filenameOnly, logTime.Format("2006-01-02"), suffix) + fName = fmt.Sprintf("%s.%s.%s", w.fileNameOnly, logTime.Format("2006-01-02"), w.suffix) _, err = os.Lstat(fName) } // return error if the last file checked still existed diff --git a/logs/files.go b/logs/files.go new file mode 100644 index 00000000..42528660 --- /dev/null +++ b/logs/files.go @@ -0,0 +1,66 @@ +package logs + +import "time" + +type filesLogWriter struct { + writers [LevelDebug + 1]*fileLogWriter +} + +func (f *filesLogWriter) Init(config string) error { + writer := newFileWriter().(*fileLogWriter) + err := writer.Init(config) + if err != nil { + return err + } + f.writers[0] = writer + + for i := LevelEmergency; i <= f.writers[0].Level; i++ { + writer = newFileWriter().(*fileLogWriter) + writer.Init(config) + writer.Level = i + writer.fileNameOnly += "." + levelNames[i] + f.writers[i+1] = writer + } + + return nil +} + +func (f *filesLogWriter) Destroy() { + for i := 0; i < len(f.writers); i++ { + if f.writers[i] != nil { + f.writers[i].Destroy() + } + } +} + +func (f *filesLogWriter) WriteMsg(when time.Time, msg string, level int) error { + if f.writers[0] != nil { + f.writers[0].WriteMsg(when, msg, level) + } + for i := 1; i < len(f.writers); i++ { + if f.writers[i] != nil { + if level == f.writers[i].Level { + f.writers[i].WriteMsg(when, msg, level) + } + } + } + return nil +} + +func (f *filesLogWriter) Flush() { + for i := 0; i < len(f.writers); i++ { + if f.writers[i] != nil { + f.writers[i].Flush() + } + } +} + + +// newFilesWriter create a FileLogWriter returning as LoggerInterface. +func newFilesWriter() Logger { + return &filesLogWriter{} +} + +func init() { + Register("files", NewConn) +} diff --git a/logs/log.go b/logs/log.go index f53d2382..e5c14dc1 100644 --- a/logs/log.go +++ b/logs/log.go @@ -64,6 +64,8 @@ const ( LevelWarn = LevelWarning ) +var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"} + type loggerType func() Logger // Logger defines the behavior of a log provider. @@ -109,7 +111,7 @@ type nameLogger struct { type logMsg struct { level int msg string - when time.Time + when time.Time } var logMsgPool *sync.Pool From f8c4b3aa4c9a2eee65e5686c99075fa0573c9212 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 3 Feb 2016 17:03:57 +0800 Subject: [PATCH 07/14] add files logger to separate different logs --- logs/files.go | 71 +++++++++++++++++++++++++++++++++++++++++--------- logs/log.go | 2 -- logs/logger.go | 15 +++++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/logs/files.go b/logs/files.go index 42528660..617af1ec 100644 --- a/logs/files.go +++ b/logs/files.go @@ -1,25 +1,71 @@ +// Copyright 2014 beego Author. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package logs -import "time" +import ( + "encoding/json" + "time" +) +// A filesLogWriter manages several fileLogWriter +// filesLogWriter will write logs to the file in json configuration and write the same level log to correspond file +// means if the file name in configuration is project.log filesLogWriter will create project.error.log/project.debug.log +// and write the error-level logs to project.error.log and write the debug-level logs to project.debug.log +// the rotate attribute also acts like fileLogWriter type filesLogWriter struct { - writers [LevelDebug + 1]*fileLogWriter + writers [LevelDebug + 1 + 1]*fileLogWriter // the last one for fullLogWriter + fullLogWriter *fileLogWriter + Separate []string `json:"separate"` } +var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"} + +// Init file logger with json config. +// jsonConfig like: +// { +// "filename":"logs/beego.log", +// "maxLines":0, +// "maxsize":0, +// "daily":true, +// "maxDays":15, +// "rotate":true, +// "perm":0600, +// "separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"], +// } + func (f *filesLogWriter) Init(config string) error { writer := newFileWriter().(*fileLogWriter) err := writer.Init(config) if err != nil { return err } - f.writers[0] = writer + f.fullLogWriter = writer + f.writers[LevelDebug+1] = writer - for i := LevelEmergency; i <= f.writers[0].Level; i++ { - writer = newFileWriter().(*fileLogWriter) - writer.Init(config) - writer.Level = i - writer.fileNameOnly += "." + levelNames[i] - f.writers[i+1] = writer + json.Unmarshal([]byte(config), f) + + for i := LevelEmergency; i < LevelDebug+1; i++ { + for _, v := range f.Separate { + if v == levelNames[i] { + writer = newFileWriter().(*fileLogWriter) + writer.Init(config) + writer.Level = i + writer.fileNameOnly += "." + levelNames[i] + f.writers[i] = writer + } + } } return nil @@ -34,10 +80,10 @@ func (f *filesLogWriter) Destroy() { } func (f *filesLogWriter) WriteMsg(when time.Time, msg string, level int) error { - if f.writers[0] != nil { - f.writers[0].WriteMsg(when, msg, level) + if f.fullLogWriter != nil { + f.fullLogWriter.WriteMsg(when, msg, level) } - for i := 1; i < len(f.writers); i++ { + for i := 0; i < len(f.writers)-1; i++ { if f.writers[i] != nil { if level == f.writers[i].Level { f.writers[i].WriteMsg(when, msg, level) @@ -55,7 +101,6 @@ func (f *filesLogWriter) Flush() { } } - // newFilesWriter create a FileLogWriter returning as LoggerInterface. func newFilesWriter() Logger { return &filesLogWriter{} diff --git a/logs/log.go b/logs/log.go index e5c14dc1..b93b276e 100644 --- a/logs/log.go +++ b/logs/log.go @@ -64,8 +64,6 @@ const ( LevelWarn = LevelWarning ) -var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"} - type loggerType func() Logger // Logger defines the behavior of a log provider. diff --git a/logs/logger.go b/logs/logger.go index ffcead2b..323c41c5 100644 --- a/logs/logger.go +++ b/logs/logger.go @@ -1,3 +1,18 @@ +// Copyright 2014 beego Author. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + package logs import ( From 1f716dda3e52653a48cdf9777ba965cd47feafa7 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 3 Feb 2016 17:54:58 +0800 Subject: [PATCH 08/14] add test files and bug fixed --- logs/files.go | 15 ++++++--- logs/files_test.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 logs/files_test.go diff --git a/logs/files.go b/logs/files.go index 617af1ec..816d42e3 100644 --- a/logs/files.go +++ b/logs/files.go @@ -17,6 +17,7 @@ package logs import ( "encoding/json" "time" + "fmt" ) // A filesLogWriter manages several fileLogWriter @@ -56,14 +57,20 @@ func (f *filesLogWriter) Init(config string) error { json.Unmarshal([]byte(config), f) + jsonMap := map[string]interface{}{} + + json.Unmarshal([]byte(config), &jsonMap) + for i := LevelEmergency; i < LevelDebug+1; i++ { for _, v := range f.Separate { if v == levelNames[i] { + jsonMap["filename"] = f.fullLogWriter.fileNameOnly + "." + levelNames[i] + f.fullLogWriter.suffix + jsonMap["level"] = i + bs, _ := json.Marshal(jsonMap) writer = newFileWriter().(*fileLogWriter) - writer.Init(config) - writer.Level = i - writer.fileNameOnly += "." + levelNames[i] + writer.Init(string(bs)) f.writers[i] = writer + fmt.Println(writer.Filename) } } } @@ -107,5 +114,5 @@ func newFilesWriter() Logger { } func init() { - Register("files", NewConn) + Register("files", newFilesWriter) } diff --git a/logs/files_test.go b/logs/files_test.go new file mode 100644 index 00000000..058ba902 --- /dev/null +++ b/logs/files_test.go @@ -0,0 +1,78 @@ +// Copyright 2014 beego Author. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package logs + +import ( + "bufio" + "os" + "strconv" + "strings" + "testing" +) + +func TestFiles_1(t *testing.T) { + log := NewLogger(10000) + log.SetLogger("files", `{"filename":"test.log","separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]}`) + log.Debug("debug") + log.Informational("info") + log.Notice("notice") + log.Warning("warning") + log.Error("error") + log.Alert("alert") + log.Critical("critical") + log.Emergency("emergency") + fns := []string{""} + fns = append(fns, levelNames[0:]...) + name := "test" + suffix := ".log" + for _, fn := range fns { + + file := name + suffix + if fn != "" { + file = name + "." + fn + suffix + } + f, err := os.Open(file) + if err != nil { + t.Fatal(err) + } + b := bufio.NewReader(f) + lineNum := 0 + lastLine := "" + for { + line, _, err := b.ReadLine() + if err != nil { + break + } + if len(line) > 0 { + lastLine = string(line) + lineNum++ + } + } + var expected = 1 + if fn == "" { + expected = LevelDebug + 1 + } + if lineNum != expected { + t.Fatal(file, "has", lineNum, "lines not "+strconv.Itoa(expected)+" lines") + } + if lineNum == 1 { + if !strings.Contains(lastLine, fn) { + t.Fatal(file + " " + lastLine + " not contains the log msg " + fn) + } + } + os.Remove(file) + } + +} From 26cc040f9aa2dd354ff623a7c6c38d2883817315 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 1 Mar 2016 17:00:24 +0800 Subject: [PATCH 09/14] daily log name dot fixed --- logs/file.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/file.go b/logs/file.go index 990a76d8..cdea1457 100644 --- a/logs/file.go +++ b/logs/file.go @@ -218,7 +218,7 @@ func (w *fileLogWriter) doRotate(logTime time.Time) error { _, err = os.Lstat(fName) } } else { - fName = fmt.Sprintf("%s.%s.%s", w.fileNameOnly, logTime.Format("2006-01-02"), w.suffix) + fName = fmt.Sprintf("%s.%s%s", w.fileNameOnly, logTime.Format("2006-01-02"), w.suffix) _, err = os.Lstat(fName) } // return error if the last file checked still existed From 387dd6ec0e751faa82c5d911f2cfc23cfff1ba4a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 1 Mar 2016 17:12:21 +0800 Subject: [PATCH 10/14] add a line of comment --- logs/files.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/logs/files.go b/logs/files.go index 816d42e3..6a0fbd7e 100644 --- a/logs/files.go +++ b/logs/files.go @@ -55,10 +55,10 @@ func (f *filesLogWriter) Init(config string) error { f.fullLogWriter = writer f.writers[LevelDebug+1] = writer + //unmarshal "separate" field to f.Separate json.Unmarshal([]byte(config), f) jsonMap := map[string]interface{}{} - json.Unmarshal([]byte(config), &jsonMap) for i := LevelEmergency; i < LevelDebug+1; i++ { @@ -70,7 +70,6 @@ func (f *filesLogWriter) Init(config string) error { writer = newFileWriter().(*fileLogWriter) writer.Init(string(bs)) f.writers[i] = writer - fmt.Println(writer.Filename) } } } From ca3c57fbc68881d3a109dea755e11359ae8bd5dc Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 1 Mar 2016 17:13:50 +0800 Subject: [PATCH 11/14] add a line of comment --- logs/files.go | 1 - 1 file changed, 1 deletion(-) diff --git a/logs/files.go b/logs/files.go index 6a0fbd7e..b312041c 100644 --- a/logs/files.go +++ b/logs/files.go @@ -17,7 +17,6 @@ package logs import ( "encoding/json" "time" - "fmt" ) // A filesLogWriter manages several fileLogWriter From 3379a2b7ed6381eac5a2b5fcfb22f0a3c02dc613 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 4 Mar 2016 10:43:57 +0800 Subject: [PATCH 12/14] remove file bug fixed remove file by filename and file suffix --- logs/file.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/logs/file.go b/logs/file.go index cdea1457..9d3f78a0 100644 --- a/logs/file.go +++ b/logs/file.go @@ -256,7 +256,8 @@ func (w *fileLogWriter) deleteOldLog() { }() if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.MaxDays) { - if strings.HasPrefix(filepath.Base(path), filepath.Base(w.Filename)) { + if strings.HasPrefix(filepath.Base(path), w.fileNameOnly) && + strings.HasSuffix(filepath.Base(path), w.suffix) { os.Remove(path) } } From 54b5120a647cc2f53b0ae5043e4e19d78504903a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 8 Mar 2016 18:43:09 +0800 Subject: [PATCH 13/14] rename files to mulitfile --- logs/{files.go => mulitfile.go} | 2 +- logs/{files_test.go => mulitfile_test.go} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename logs/{files.go => mulitfile.go} (98%) rename logs/{files_test.go => mulitfile_test.go} (92%) diff --git a/logs/files.go b/logs/mulitfile.go similarity index 98% rename from logs/files.go rename to logs/mulitfile.go index b312041c..599870f8 100644 --- a/logs/files.go +++ b/logs/mulitfile.go @@ -112,5 +112,5 @@ func newFilesWriter() Logger { } func init() { - Register("files", newFilesWriter) + Register("mulitfile", newFilesWriter) } diff --git a/logs/files_test.go b/logs/mulitfile_test.go similarity index 92% rename from logs/files_test.go rename to logs/mulitfile_test.go index 058ba902..5e1e3f06 100644 --- a/logs/files_test.go +++ b/logs/mulitfile_test.go @@ -24,7 +24,7 @@ import ( func TestFiles_1(t *testing.T) { log := NewLogger(10000) - log.SetLogger("files", `{"filename":"test.log","separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]}`) + log.SetLogger("mulitfile", `{"filename":"test.log","separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]}`) log.Debug("debug") log.Informational("info") log.Notice("notice") From b2f071395bcc3305687aa061dc1e57402f4d26fe Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 8 Mar 2016 18:44:39 +0800 Subject: [PATCH 14/14] rename files to mulitfile --- logs/mulitfile.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/logs/mulitfile.go b/logs/mulitfile.go index 599870f8..cf22f7a8 100644 --- a/logs/mulitfile.go +++ b/logs/mulitfile.go @@ -24,7 +24,7 @@ import ( // means if the file name in configuration is project.log filesLogWriter will create project.error.log/project.debug.log // and write the error-level logs to project.error.log and write the debug-level logs to project.debug.log // the rotate attribute also acts like fileLogWriter -type filesLogWriter struct { +type mulitFileLogWriter struct { writers [LevelDebug + 1 + 1]*fileLogWriter // the last one for fullLogWriter fullLogWriter *fileLogWriter Separate []string `json:"separate"` @@ -45,7 +45,7 @@ var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning // "separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"], // } -func (f *filesLogWriter) Init(config string) error { +func (f *mulitFileLogWriter) Init(config string) error { writer := newFileWriter().(*fileLogWriter) err := writer.Init(config) if err != nil { @@ -76,7 +76,7 @@ func (f *filesLogWriter) Init(config string) error { return nil } -func (f *filesLogWriter) Destroy() { +func (f *mulitFileLogWriter) Destroy() { for i := 0; i < len(f.writers); i++ { if f.writers[i] != nil { f.writers[i].Destroy() @@ -84,7 +84,7 @@ func (f *filesLogWriter) Destroy() { } } -func (f *filesLogWriter) WriteMsg(when time.Time, msg string, level int) error { +func (f *mulitFileLogWriter) WriteMsg(when time.Time, msg string, level int) error { if f.fullLogWriter != nil { f.fullLogWriter.WriteMsg(when, msg, level) } @@ -98,7 +98,7 @@ func (f *filesLogWriter) WriteMsg(when time.Time, msg string, level int) error { return nil } -func (f *filesLogWriter) Flush() { +func (f *mulitFileLogWriter) Flush() { for i := 0; i < len(f.writers); i++ { if f.writers[i] != nil { f.writers[i].Flush() @@ -108,7 +108,7 @@ func (f *filesLogWriter) Flush() { // newFilesWriter create a FileLogWriter returning as LoggerInterface. func newFilesWriter() Logger { - return &filesLogWriter{} + return &mulitFileLogWriter{} } func init() {