blob: 1bfd95d18319fbe241ddb255c59c2b92eb2f3903 [file] [log] [blame]
// Copyright 2016 ~ 2018 AlexStocks(https://github.com/AlexStocks).
// All rights reserved. Use of this source code is
// governed by Apache License 2.0.
// based on log4go.
package gxlog
import (
"fmt"
"path/filepath"
"runtime"
"strings"
"time"
)
import (
gxos "github.com/AlexStocks/goext/os"
"github.com/AlexStocks/log4go"
)
const (
logSuffix = ".log"
wfLogSuffix = ".wf.log"
)
type Conf struct {
Name string // application name
Dir string // logger directory
Level string // minimum log level
Console bool // whether output log to console
Daily bool // whether rotate log file at mid-night every day
BackupNum int // log file backup number. the oldest is deleted.
BufSize int // async logger buffer size
Json bool // whether output json log
}
type Logger struct {
log4go.Logger
}
// init a logger
func NewLogger(conf Conf) (Logger, error) {
var (
err error
fileName string
logger log4go.Logger
fileLogger *log4go.FileLogWriter
)
if err = gxos.CreateDir(conf.Dir); err != nil {
log4go.Error("goext.os.CreateDir(%s) = error{%#v}", conf.Dir, err)
return Logger{logger}, err
}
logger = log4go.NewLogger()
if conf.Console {
logger.AddFilter("stdout", logLevel(conf.Level), log4go.NewConsoleLogWriter(conf.Json))
}
// create file writer for all log level
fileName = comLogFileName(conf.Name, conf.Dir, false)
fileLogger = log4go.NewFileLogWriter(fileName, true, conf.BufSize)
if fileLogger == nil {
return Logger{logger}, fmt.Errorf("log4go.NewFileLogWriter(%s) = nil", fileName)
}
fileLogger.SetJson(conf.Json)
fileLogger.SetFormat(log4go.FORMAT_DEFAULT)
if conf.Daily {
fileLogger.SetRotateDaily(true)
}
if 0 < conf.BackupNum {
fileLogger.SetRotateMaxBackup(conf.BackupNum)
}
logger.AddFilter("log", logLevel(conf.Level), fileLogger)
// create file writer for warning & fatal & critical
fileName = comLogFileName(conf.Name, conf.Dir, true)
fileLogger = log4go.NewFileLogWriter(fileName, true, conf.BufSize)
if fileLogger == nil {
return Logger{logger}, fmt.Errorf("log4go.NewFileLogWriter(%s) = nil", fileName)
}
fileLogger.SetJson(conf.Json)
fileLogger.SetFormat(log4go.FORMAT_DEFAULT)
if conf.Daily {
fileLogger.SetRotateDaily(true)
}
if 0 < conf.BackupNum {
fileLogger.SetRotateMaxBackup(conf.BackupNum)
}
logger.AddFilter("wflog", log4go.WARNING, fileLogger)
return Logger{logger}, nil
}
func NewLoggerWithConfFile(conf string) Logger {
logger := log4go.NewLogger()
return Logger{(&logger).LoadConfiguration(conf)}
}
func comLogFileName(appName string, dir string, err bool) string {
strings.TrimSuffix(dir, "/")
if err {
// log level warning, error, critical
return filepath.Join(dir, appName+wfLogSuffix)
}
return filepath.Join(dir, appName+logSuffix)
}
func logLevel(str string) log4go.Level {
switch strings.ToUpper(str) {
case "DEBUG":
return log4go.DEBUG
case "TRACE":
return log4go.TRACE
case "INFO":
return log4go.INFO
case "WARN":
return log4go.WARNING
case "ERROR":
return log4go.ERROR
case "CRITIC":
return log4go.CRITICAL
case "CRITICAL":
return log4go.CRITICAL
default:
return log4go.INFO
}
}
func funcFileLine() string {
tm := time.Unix(time.Now().Unix(), 0)
funcName, file, line, _ := runtime.Caller(3)
return "[" + tm.Format("2006-01-02/15:04:05 ") +
runtime.FuncForPC(funcName).Name() +
": " + filepath.Base(file) +
": " + fmt.Sprintf("%d", line) +
"] "
}