mirror of
https://github.com/astaxie/beego.git
synced 2024-11-16 16:30:54 +00:00
Merge pull request #1721 from JessonChan/log_enhancement
Log enhancement
This commit is contained in:
commit
d86ab2ed31
17
logs/conn.go
17
logs/conn.go
@ -17,7 +17,6 @@ package logs
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -25,7 +24,7 @@ import (
|
|||||||
// connWriter implements LoggerInterface.
|
// connWriter implements LoggerInterface.
|
||||||
// it writes messages in keep-live tcp connection.
|
// it writes messages in keep-live tcp connection.
|
||||||
type connWriter struct {
|
type connWriter struct {
|
||||||
lg *log.Logger
|
lg *logWriter
|
||||||
innerWriter io.WriteCloser
|
innerWriter io.WriteCloser
|
||||||
ReconnectOnMsg bool `json:"reconnectOnMsg"`
|
ReconnectOnMsg bool `json:"reconnectOnMsg"`
|
||||||
Reconnect bool `json:"reconnect"`
|
Reconnect bool `json:"reconnect"`
|
||||||
@ -43,8 +42,8 @@ func NewConn() Logger {
|
|||||||
|
|
||||||
// Init init connection writer with json config.
|
// Init init connection writer with json config.
|
||||||
// json config only need key "level".
|
// json config only need key "level".
|
||||||
func (c *connWriter) Init(jsonconfig string) error {
|
func (c *connWriter) Init(jsonConfig string) error {
|
||||||
return json.Unmarshal([]byte(jsonconfig), c)
|
return json.Unmarshal([]byte(jsonConfig), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in connection.
|
// 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 {
|
if level > c.Level {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if c.neddedConnectOnMsg() {
|
if c.needToConnectOnMsg() {
|
||||||
err := c.connect()
|
err := c.connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -64,9 +63,7 @@ func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
|
|||||||
defer c.innerWriter.Close()
|
defer c.innerWriter.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = formatLogTime(when) + msg
|
c.lg.println(when, msg)
|
||||||
|
|
||||||
c.lg.Println(msg)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,11 +95,11 @@ func (c *connWriter) connect() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.innerWriter = conn
|
c.innerWriter = conn
|
||||||
c.lg = log.New(conn, "", 0)
|
c.lg = newLogWriter(conn)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connWriter) neddedConnectOnMsg() bool {
|
func (c *connWriter) needToConnectOnMsg() bool {
|
||||||
if c.Reconnect {
|
if c.Reconnect {
|
||||||
c.Reconnect = false
|
c.Reconnect = false
|
||||||
return true
|
return true
|
||||||
|
@ -16,7 +16,6 @@ package logs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
@ -47,7 +46,7 @@ var colors = []brush{
|
|||||||
|
|
||||||
// consoleWriter implements LoggerInterface and writes messages to terminal.
|
// consoleWriter implements LoggerInterface and writes messages to terminal.
|
||||||
type consoleWriter struct {
|
type consoleWriter struct {
|
||||||
lg *log.Logger
|
lg *logWriter
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
|
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.
|
// NewConsole create ConsoleWriter returning as LoggerInterface.
|
||||||
func NewConsole() Logger {
|
func NewConsole() Logger {
|
||||||
cw := &consoleWriter{
|
cw := &consoleWriter{
|
||||||
lg: log.New(os.Stdout, "", 0),
|
lg: newLogWriter(os.Stdout),
|
||||||
Level: LevelDebug,
|
Level: LevelDebug,
|
||||||
Colorful: true,
|
Colorful: true,
|
||||||
}
|
}
|
||||||
@ -80,12 +79,10 @@ func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error {
|
|||||||
if level > c.Level {
|
if level > c.Level {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
msg = formatLogTime(when) + msg
|
|
||||||
if c.Colorful {
|
if c.Colorful {
|
||||||
c.lg.Println(colors[level](msg))
|
msg = colors[level](msg)
|
||||||
} else {
|
|
||||||
c.lg.Println(msg)
|
|
||||||
}
|
}
|
||||||
|
c.lg.println(when, msg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
logs/file.go
31
logs/file.go
@ -53,9 +53,11 @@ type fileLogWriter struct {
|
|||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
|
|
||||||
Perm os.FileMode `json:"perm"`
|
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.
|
// newFileWriter create a FileLogWriter returning as LoggerInterface.
|
||||||
func newFileWriter() Logger {
|
func newFileWriter() Logger {
|
||||||
w := &fileLogWriter{
|
w := &fileLogWriter{
|
||||||
Filename: "",
|
Filename: "",
|
||||||
@ -89,6 +91,11 @@ func (w *fileLogWriter) Init(jsonConfig string) error {
|
|||||||
if len(w.Filename) == 0 {
|
if len(w.Filename) == 0 {
|
||||||
return errors.New("jsonconfig must have filename")
|
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()
|
err = w.startLogger()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -118,10 +125,9 @@ func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
|
|||||||
if level > w.Level {
|
if level > w.Level {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
msg = formatLogTime(when) + msg + "\n"
|
h, d := formatTimeHeader(when)
|
||||||
|
msg = string(h) + msg + "\n"
|
||||||
if w.Rotate {
|
if w.Rotate {
|
||||||
d := when.Day()
|
|
||||||
if w.needRotate(len(msg), d) {
|
if w.needRotate(len(msg), d) {
|
||||||
w.Lock()
|
w.Lock()
|
||||||
if w.needRotate(len(msg), d) {
|
if w.needRotate(len(msg), d) {
|
||||||
@ -196,7 +202,7 @@ func (w *fileLogWriter) lines() (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DoRotate means it need to write file in new file.
|
// 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 {
|
func (w *fileLogWriter) doRotate(logTime time.Time) error {
|
||||||
_, err := os.Lstat(w.Filename)
|
_, err := os.Lstat(w.Filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -206,13 +212,13 @@ func (w *fileLogWriter) doRotate(logTime time.Time) error {
|
|||||||
// Find the next available number
|
// Find the next available number
|
||||||
num := 1
|
num := 1
|
||||||
fName := ""
|
fName := ""
|
||||||
suffix := filepath.Ext(w.Filename)
|
if w.MaxLines > 0 || w.MaxSize > 0 {
|
||||||
filenameOnly := strings.TrimSuffix(w.Filename, suffix)
|
|
||||||
if suffix == "" {
|
|
||||||
suffix = ".log"
|
|
||||||
}
|
|
||||||
for ; err == nil && num <= 999; num++ {
|
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", w.fileNameOnly, logTime.Format("2006-01-02"), w.suffix)
|
||||||
_, err = os.Lstat(fName)
|
_, err = os.Lstat(fName)
|
||||||
}
|
}
|
||||||
// return error if the last file checked still existed
|
// return error if the last file checked still existed
|
||||||
@ -250,7 +256,8 @@ func (w *fileLogWriter) deleteOldLog() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.MaxDays) {
|
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)
|
os.Remove(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
logs/log.go
42
logs/log.go
@ -412,45 +412,3 @@ func (bl *BeeLogger) flush() {
|
|||||||
l.Flush()
|
l.Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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:])
|
|
||||||
}
|
|
||||||
|
80
logs/logger.go
Normal file
80
logs/logger.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// 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 (
|
||||||
|
"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
|
||||||
|
}
|
116
logs/mulitfile.go
Normal file
116
logs/mulitfile.go
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// 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 (
|
||||||
|
"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 mulitFileLogWriter struct {
|
||||||
|
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 *mulitFileLogWriter) Init(config string) error {
|
||||||
|
writer := newFileWriter().(*fileLogWriter)
|
||||||
|
err := writer.Init(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
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++ {
|
||||||
|
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(string(bs))
|
||||||
|
f.writers[i] = writer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *mulitFileLogWriter) Destroy() {
|
||||||
|
for i := 0; i < len(f.writers); i++ {
|
||||||
|
if f.writers[i] != nil {
|
||||||
|
f.writers[i].Destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *mulitFileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
|
if f.fullLogWriter != nil {
|
||||||
|
f.fullLogWriter.WriteMsg(when, msg, level)
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *mulitFileLogWriter) 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 &mulitFileLogWriter{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register("mulitfile", newFilesWriter)
|
||||||
|
}
|
78
logs/mulitfile_test.go
Normal file
78
logs/mulitfile_test.go
Normal file
@ -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("mulitfile", `{"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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user