init log
This commit is contained in:
parent
6c6c00caea
commit
e0ac82bdaf
262
log.go
Normal file
262
log.go
Normal file
@ -0,0 +1,262 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"qoobing.com/gomod/str"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
glogger *log.Logger = nil
|
||||
once sync.Once = sync.Once{}
|
||||
mylogger *Logger = nil
|
||||
modellogs map[string]*Logger = map[string]*Logger{}
|
||||
)
|
||||
|
||||
const ErrLogPanic = "~~~~panic~~~~~~"
|
||||
|
||||
//////////////global log//////////////////begin///////////////////
|
||||
|
||||
func PrintPreety(prefix string, v interface{}) {
|
||||
mylogger.PrintPreety(prefix, v)
|
||||
}
|
||||
func DebugfWithDepth(calldepth int, format string, v ...interface{}) {
|
||||
mylogger.DebugfWithDepth(calldepth, format, v...)
|
||||
}
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
mylogger.Debugf(format, v...)
|
||||
}
|
||||
func Noticef(format string, v ...interface{}) {
|
||||
mylogger.Noticef(format, v...)
|
||||
}
|
||||
func NoticefWithDepth(calldepth int, format string, v ...interface{}) {
|
||||
mylogger.NoticefWithDepth(calldepth, format, v...)
|
||||
}
|
||||
func Warningf(format string, v ...interface{}) {
|
||||
mylogger.Warningf(format, v...)
|
||||
}
|
||||
func Panicf(format string, v ...interface{}) {
|
||||
mylogger.Panicf(format, v...)
|
||||
}
|
||||
func Fatalf(format string, v ...interface{}) {
|
||||
mylogger.Fatalf(format, v...)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
type Logger struct {
|
||||
model string
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
func New(model string) (logger *Logger) {
|
||||
if model == "" {
|
||||
model = "undefine"
|
||||
}
|
||||
if _, ok := modellogs[model]; ok{
|
||||
return modellogs[model]
|
||||
}else{
|
||||
modellogs[model] = &Logger{model: model, logger: glogger}
|
||||
return modellogs[model]
|
||||
}
|
||||
}
|
||||
|
||||
func (log *Logger) Print(prefix string, v interface{}) {
|
||||
preety, _ := json.Marshal(v)
|
||||
log.logwrite("DEBUGE", 3, prefix+"%s\n", preety)
|
||||
}
|
||||
func (log *Logger) PrintPreety(prefix string, v interface{}) {
|
||||
preety, _ := json.MarshalIndent(v, "==", " ")
|
||||
log.logwrite("DEBUGE", 3, prefix+"%s\n", preety)
|
||||
}
|
||||
|
||||
func (log *Logger) Debugf(format string, v ...interface{}) {
|
||||
log.logwrite("DEBUGE", 3, format, v...)
|
||||
}
|
||||
|
||||
func (log *Logger) DebugfWithDepth(calldepth int, format string, v ...interface{}) {
|
||||
calldepth += 3
|
||||
log.logwrite("DEBUGE", calldepth, format, v...)
|
||||
}
|
||||
|
||||
func (log *Logger) Noticef(format string, v ...interface{}) {
|
||||
log.logwrite("NOTICE", 3, format, v...)
|
||||
}
|
||||
|
||||
func (log *Logger) NoticefWithDepth(calldepth int, format string, v ...interface{}) {
|
||||
calldepth += 3
|
||||
log.logwrite("NOTICE", calldepth, format, v...)
|
||||
}
|
||||
|
||||
func (log *Logger) Warningf(format string, v ...interface{}) {
|
||||
log.logwrite("WARNING", 3, format, v...)
|
||||
}
|
||||
|
||||
func (log *Logger) Fatalf(format string, v ...interface{}) {
|
||||
log.logwrite("FATAL", 3, format, v...)
|
||||
}
|
||||
|
||||
func (log *Logger) Panicf(format string, v ...interface{}) {
|
||||
log.logwrite("PANIC", 3, format, v...)
|
||||
}
|
||||
|
||||
func (log *Logger) logwrite(typ string, calldepth int, format string, v ...interface{}) {
|
||||
var (
|
||||
l = gls.GetGlsValue("logid")
|
||||
id = "0"
|
||||
)
|
||||
if l != nil {
|
||||
id = l.(string)
|
||||
}
|
||||
format = strings.Trim(format, "\n")
|
||||
|
||||
switch typ {
|
||||
case "PANIC":
|
||||
log.logger.SetPrefix("\x1b[31m" + "PANIC [" + id + "] [" + log.model + "] ")
|
||||
case "FATAL":
|
||||
log.logger.SetPrefix("\x1b[31m" + "FATAL [" + id + "] [" + log.model + "] ")
|
||||
case "WARNING":
|
||||
log.logger.SetPrefix("\x1b[32m" + "WARNING [" + id + "] [" + log.model + "] ")
|
||||
case "NOTICE":
|
||||
log.logger.SetPrefix("NOTICE [" + id + "] [" + log.model + "] ")
|
||||
case "DEBUGE":
|
||||
log.logger.SetPrefix("DEBUGE [" + id + "] [" + log.model + "] ")
|
||||
default:
|
||||
log.logger.SetPrefix("UNKNOWN [" + id + "] [" + log.model + "] ")
|
||||
}
|
||||
|
||||
if mylogger == log {
|
||||
calldepth = calldepth + 1
|
||||
}
|
||||
|
||||
if typ == "FATAL" || typ == "WARNING" {
|
||||
log.logger.Output(calldepth, fmt.Sprintf(format+"\x1b[0m\n", v...))
|
||||
} else if typ == "NOTICE" {
|
||||
calldepth = calldepth + 2
|
||||
log.logger.Output(calldepth, fmt.Sprintf(format+"\n", v...))
|
||||
} else if typ == "PANIC" {
|
||||
stack := strings.Replace(string(debug.Stack()), "\n", "\n== ", -1)
|
||||
stack = str.SkipLine(stack, calldepth*2+1)
|
||||
v = append(v, stack)
|
||||
panicstr := fmt.Sprintf(format+"\x1b[0m. Panic stack:\n%s\n", v...)
|
||||
log.logger.Output(calldepth, panicstr)
|
||||
panic(ErrLogPanic)
|
||||
} else {
|
||||
log.logger.Output(calldepth, fmt.Sprintf(format+"\n", v...))
|
||||
}
|
||||
}
|
||||
|
||||
//////////////global log trace//////////////////begin///////////////////
|
||||
|
||||
func TRACE_INTO(format string, v ...interface{}) string {
|
||||
_, fn, line, _ := runtime.Caller(1)
|
||||
strfn := fmt.Sprintf("%s:%d", fn, line)
|
||||
Debugf("TRACE into ["+strfn+"]"+format+"...\r\n", v...)
|
||||
|
||||
return strfn
|
||||
}
|
||||
|
||||
func TRACE_EXIT(strfn string, format string, v ...interface{}) {
|
||||
Debugf("TRACE exit ["+strfn+"]"+format+"...\r\n", v...)
|
||||
}
|
||||
|
||||
type mWriter struct {
|
||||
logw *os.File
|
||||
stdw *os.File
|
||||
}
|
||||
|
||||
func (w mWriter) Write(p []byte) (n int, err error) {
|
||||
if flagcachelog {
|
||||
logCache.Write(p)
|
||||
}
|
||||
w.stdw.Write(p)
|
||||
return w.logw.Write(p)
|
||||
}
|
||||
|
||||
var cacheLogLock = new(sync.Mutex)
|
||||
var flagcachelog = false
|
||||
var logCache = bytes.Buffer{}
|
||||
|
||||
func StartCacheLog() {
|
||||
cacheLogLock.Lock()
|
||||
flagcachelog = true
|
||||
logCache.Reset()
|
||||
}
|
||||
func StopCacheLog() {
|
||||
cacheLogLock.Unlock()
|
||||
flagcachelog = false
|
||||
}
|
||||
func GetCacheLog() string {
|
||||
if flagcachelog != true {
|
||||
panic("GetCacheLog MUST call after StartCacheLog called")
|
||||
}
|
||||
return logCache.String()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////Initialize/////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
func init() {
|
||||
once.Do(initlog)
|
||||
}
|
||||
|
||||
func initlog() {
|
||||
var mwriter mWriter
|
||||
var openlog = func(logname string) *log.Logger {
|
||||
fp, err := os.OpenFile(logname, os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
||||
if err != nil {
|
||||
panic("open log file failed:" + err.Error())
|
||||
}
|
||||
mwriter.logw.Close()
|
||||
mwriter.logw = fp
|
||||
mwriter.stdw = os.Stdout
|
||||
glogger = log.New(mwriter, "", log.Ldate|log.Lmicroseconds|log.Lshortfile)
|
||||
return glogger
|
||||
}
|
||||
|
||||
_, logfilename := filepath.Split(os.Args[0])
|
||||
LOGSPLITTIME := "20060102" //20060102150405
|
||||
LOGFILENAME := "log/" + logfilename + ".log"
|
||||
|
||||
glogger = openlog(LOGFILENAME)
|
||||
mylogger = New("system")
|
||||
curhourtime := time.Now().Local().Format(LOGSPLITTIME)
|
||||
prehourtime := curhourtime
|
||||
|
||||
go func() {
|
||||
intva := 2 * time.Minute
|
||||
timer := time.NewTimer(1 * time.Second)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timer.C:
|
||||
curhourtime := time.Now().Local().Format(LOGSPLITTIME)
|
||||
//Debugf("check logfile: prehourtime:%s,curhourtime:%s", prehourtime, curhourtime)
|
||||
if prehourtime != curhourtime {
|
||||
// close old logger & move log to backup file.
|
||||
PREFILENAME := LOGFILENAME + "." + prehourtime
|
||||
os.Rename(LOGFILENAME, PREFILENAME)
|
||||
prehourtime = curhourtime
|
||||
|
||||
glogger = openlog(LOGFILENAME)
|
||||
mylogger = New("system")
|
||||
for _, l := range modellogs{
|
||||
l.logger = glogger
|
||||
}
|
||||
}
|
||||
|
||||
timer.Reset(intva)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
Loading…
Reference in New Issue
Block a user