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