初始版本
diff --git a/golog.go b/golog.go
new file mode 100644
index 0000000..fd59e07
--- /dev/null
+++ b/golog.go
@@ -0,0 +1,216 @@
+package golog
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "time"
+
+ log "github.com/go-playground/log"
+)
+
+var logLevelsArray = []log.Level{log.DebugLevel,
+ log.TraceLevel,
+ log.InfoLevel,
+ log.NoticeLevel,
+ log.WarnLevel,
+ log.ErrorLevel,
+ log.PanicLevel,
+ log.AlertLevel,
+ log.FatalLevel}
+
+func getLogLevels(l log.Level) []log.Level {
+ levels := make([]log.Level, 0)
+ offset := int(l)
+ levels = append(levels, logLevelsArray[offset:]...)
+ return levels
+}
+
+func RegisterHandler(handler log.Handler, l log.Level) {
+ log.RegisterHandler(handler, getLogLevels(l)...)
+}
+
+type BaseLogHandler struct {
+}
+
+func (l *BaseLogHandler) FormatMessage(e *log.Entry, w io.Writer) {
+ now := e.Timestamp.In(time.Local)
+ fmt.Fprintf(w, "[%s] %s - %s", e.Level,
+ now.Format(l.getDefaultTimeLayout()), e.Message)
+ for _, f := range e.Fields {
+ fmt.Fprintf(w, " %s=%v", f.Key, f.Value)
+ }
+ w.Write([]byte("\n"))
+}
+
+func (l *BaseLogHandler) getDefaultTimeLayout() string {
+ return "2006-01-02 15:04:05.000"
+}
+
+type FileLogHandler struct {
+ *BaseLogHandler
+ logFilePath string
+ logHandler *os.File
+}
+
+func checkAndCreateDir(path string) error {
+ if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
+ if err = os.MkdirAll(path, os.ModeDir|os.ModePerm); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func NewFileLogHandler(logPath string) *FileLogHandler {
+ res := new(FileLogHandler)
+ res.logFilePath = logPath
+ return res
+}
+
+func (h *FileLogHandler) openLogFile() error {
+ dir := filepath.Dir(h.logFilePath)
+ var err error
+ if err = checkAndCreateDir(dir); err != nil {
+ return err
+ }
+ if h.logHandler, err = os.OpenFile(h.logFilePath,
+ os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (h *FileLogHandler) Run() chan<- *log.Entry {
+ if err := h.openLogFile(); err != nil {
+ panic(fmt.Sprintf("Can't open log file, Err=%v\n", err))
+ }
+ ch := make(chan *log.Entry, 5)
+ go func(entries <-chan *log.Entry) {
+ var e *log.Entry
+ b := new(bytes.Buffer)
+ defer h.logHandler.Close()
+ for e = range entries {
+
+ b.Reset()
+ h.FormatMessage(e, b)
+ io.Copy(h.logHandler, b)
+ h.logHandler.Sync()
+ e.Consumed()
+ }
+ }(ch)
+ return ch
+}
+
+type RotateFileLogHandler struct {
+ *BaseLogHandler
+ logFilePath string
+ maxLogSize int64
+ maxLogFileCount int
+ logCurrentSize int64
+ logHandler *os.File
+}
+
+// NewRotateFileLogHandler
+// maxSize in MB
+func NewRotateFileLogHandler(logPath string, maxSize int, maxCount int) *RotateFileLogHandler {
+ res := new(RotateFileLogHandler)
+ res.logFilePath = logPath
+ if maxSize < 1 || maxSize > 2000 {
+ maxSize = 50
+ }
+ res.maxLogFileCount = maxCount
+ res.maxLogSize = int64(maxSize) * 1024 * 1024
+ return res
+}
+
+func (h *RotateFileLogHandler) checkFile() error {
+ var err error
+ dir := filepath.Dir(h.logFilePath)
+ if err = checkAndCreateDir(dir); err != nil {
+ return err
+ }
+ if h.logHandler, err = os.OpenFile(h.logFilePath,
+ os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
+ return err
+ }
+ h.logHandler.Seek(0, os.SEEK_SET)
+ n, _ := h.logHandler.Seek(0, os.SEEK_END)
+ h.logCurrentSize = n
+ return nil
+}
+
+func (h *RotateFileLogHandler) rotate() error {
+ var backupFilePath string
+ minModTime := time.Now()
+ backupExists := true
+ for i := 0; i < h.maxLogFileCount; i++ {
+ fullPath := fmt.Sprintf("%v.%d", h.logFilePath, i+1)
+ if stat, err := os.Stat(fullPath); err != nil {
+ if os.IsNotExist(err) {
+ backupFilePath = fullPath
+ backupExists = false
+ break
+ } else {
+ return err
+ }
+ } else {
+ if stat.ModTime().Before(minModTime) {
+ minModTime = stat.ModTime()
+ backupFilePath = fullPath
+ }
+ }
+ }
+ if backupExists && len(backupFilePath) > 0 {
+ os.Remove(backupFilePath)
+ }
+ if len(backupFilePath) > 0 {
+ var err error
+ h.logHandler.Close()
+ h.logHandler = nil
+ err = os.Rename(h.logFilePath, backupFilePath)
+ if err != nil {
+ fmt.Printf("Rename file Error=%v\n", err)
+ }
+ // if stat, err := os.Stat(backupFilePath); err == nil {
+ // fmt.Printf("Backup file size:<%v>%v\n", backupFilePath, stat.Size())
+ // }
+ h.logHandler, err = os.OpenFile(h.logFilePath,
+ os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0660)
+ if err != nil {
+ return err
+ }
+ h.logCurrentSize = 0
+ }
+ return nil
+}
+
+func (h *RotateFileLogHandler) Run() chan<- *log.Entry {
+ if err := h.checkFile(); err != nil {
+ panic(fmt.Sprintf("Can't create file, Err=%v", err))
+ }
+ ch := make(chan *log.Entry, 5)
+ go func(entries <-chan *log.Entry) {
+ var e *log.Entry
+ b := new(bytes.Buffer)
+ defer h.logHandler.Close()
+ for e = range entries {
+
+ b.Reset()
+ h.FormatMessage(e, b)
+ h.logCurrentSize += int64(b.Len())
+ if h.logHandler != nil {
+ io.Copy(h.logHandler, b)
+ // h.logHandler.Sync()
+ if h.logCurrentSize >= h.maxLogSize {
+ //fmt.Printf("Current Size=%v, old=%v\n", h.logCurrentSize, h.maxLogSize)
+ h.rotate()
+ }
+ }
+ e.Consumed()
+ }
+ }(ch)
+ return ch
+}