func (l *Logger) Panicf(format string, v ...interface{}) {
	s := fmt.Sprintf(format, v...)
	l.Output(PANIC, 2, s)
	panic(s)
}
Panicf is equivalent to l.Printf() followed by a call to panic().
package logger
import (
	"bytes"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"
	"sync"
	"time"
)
const (
	Ldate         = 1 << iota      
	Ltime                          
	Lmicroseconds                  
	Llongfile                      
	Lshortfile                     
	Lmodule                        
	Llevel                         
	LstdFlags     = Ldate | Ltime  
	Ldefault      = Llevel | Lshortfile | LstdFlags
)  
const (
	DEBUG = iota
	INFO
	WARN
	ERROR
	PANIC
	FATAL
)
const LOG_SUFIX = ".log"
var LEVEL_NAMES = []string{
	"[DEBUG]",
	"[INFO]",
	"[WARN]",
	"[ERROR]",
	"[PANIC]",
	"[FATAL]",
}
type Logger struct {
	mu         sync.Mutex    
	prefix     string        
	flag       int           
	out        io.Writer     
	buf        bytes.Buffer  
	level      int
	levelStats [6]int64
	logPath    string
	logFile    string
	create     time.Time
}
var isConsole = false
func SetConsole(_isConsole bool) {
	isConsole = _isConsole
}
var console = &Logger{out: os.Stdout, prefix: "", level: DEBUG, flag: Ldefault}
var std *Logger
func Init(logPath string, logFile string, level int) error {
	std = &Logger{
		prefix:  "",
		level:   level,
		flag:    Ldefault,
		logPath: logPath,
		logFile: logFile,
		create:  time.Now(),
	}
	out, err := os.OpenFile(std.logfileFullName(), os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		console.Error(err)
		return err
	}
	std.out = out
	return nil
}
const DATE_FORMAT = "2006-01-02"
func (l *Logger) logfileName() string {
	return l.logFile + "." + l.create.Format(DATE_FORMAT) + LOG_SUFIX
}
func (l *Logger) logfileFullName() string {
	return l.logPath + "/" + l.logFile + "." + l.create.Format(DATE_FORMAT) + LOG_SUFIX
}
func itoa(buf *bytes.Buffer, i int, wid int) {
	var u uint = uint(i)
	if u == 0 && wid <= 1 {
		buf.WriteByte('0')
		return
	}
	var b [32]byte
	bp := len(b)
	for ; u > 0 || wid > 0; u /= 10 {
		bp--
		wid--
		b[bp] = byte(u%10) + '0'
	}
	for bp < len(b) {
		buf.WriteByte(b[bp])
		bp++
	}
}
func moduleOf(file string) string {
	pos := strings.LastIndex(file, "/")
	if pos != -1 {
		pos1 := strings.LastIndex(file[:pos], "/src/")
		if pos1 != -1 {
			return file[pos1+5 : pos]
		}
	}
	return "UNKNOWN"
}
func (l *Logger) formatHeader(buf *bytes.Buffer, t time.Time, file string, line int, lvl int) {
	if l.prefix != "" {
		buf.WriteString(l.prefix)
	}
	if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
		if l.flag&Ldate != 0 {
			year, month, day := t.Date()
			itoa(buf, year, 4)
			buf.WriteByte('/')
			itoa(buf, int(month), 2)
			buf.WriteByte('/')
			itoa(buf, day, 2)
			buf.WriteByte(' ')
		}
		if l.flag&(Ltime|Lmicroseconds) != 0 {
			hour, min, sec := t.Clock()
			itoa(buf, hour, 2)
			buf.WriteByte(':')
			itoa(buf, min, 2)
			buf.WriteByte(':')
			itoa(buf, sec, 2)
			if l.flag&Lmicroseconds != 0 {
				buf.WriteByte('.')
				itoa(buf, t.Nanosecond()/1e3, 6)
			}
			buf.WriteByte(' ')
		}
	}
	if l.flag&Llevel != 0 {
		buf.WriteString(LEVEL_NAMES[lvl])
	}
	if l.flag&Lmodule != 0 {
		buf.WriteByte('[')
		buf.WriteString(moduleOf(file))
		buf.WriteByte(']')
		buf.WriteByte(' ')
	}
	if l.flag&(Lshortfile|Llongfile) != 0 {
		if l.flag&Lshortfile != 0 {
			short := file
			for i := len(file) - 1; i > 0; i-- {
				if file[i] == '/' {
					short = file[i+1:]
					break
				}
			}
			file = short
		}
		buf.WriteString(file)
		buf.WriteByte(':')
		itoa(buf, line, -1)
		buf.WriteString(": ")
	}
}
func (l *Logger) Output(level int, callDepth int, s string) error {
	if level < l.level {
		return nil
	}
	if err := l.checkFile(); err != nil {
		return err
	}
	now := time.Now()  
	var file string
	var line int
	l.mu.Lock()
	defer l.mu.Unlock()
	if l.flag&(Lshortfile|Llongfile|Lmodule) != 0 {
		l.mu.Unlock()
		var ok bool
		_, file, line, ok = runtime.Caller(callDepth)
		if !ok {
			file = "???"
			line = 0
		}
		l.mu.Lock()
	}
	l.levelStats[level]++
	l.buf.Reset()
	l.formatHeader(&l.buf, now, file, line, level)
	l.buf.WriteString(s)
	if len(s) > 0 && s[len(s)-1] != '\n' {
		l.buf.WriteByte('\n')
	}
	_, err := l.out.Write(l.buf.Bytes())
	return err
}
func (l *Logger) checkFile() error {
	now := time.Now()
	if (now.Year() > l.create.Year()) || (now.Month() > l.create.Month()) || (now.Day() > l.create.Day()) {
		l.mu.Lock()
		defer l.mu.Unlock()
		l.create = now
		newOut, err := os.OpenFile(l.logfileFullName(), os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
		if err != nil {
			console.Error(err)
			return err
		}
		if f, ok := l.out.(*os.File); ok {
			if err := f.Close(); err != nil {
				console.Error(err)
				return err
			}
		}
		l.out = newOut
	}
	return nil
}
func (l *Logger) Printf(format string, v ...interface{}) {
	l.Output(INFO, 2, fmt.Sprintf(format, v...))
}
func (l *Logger) Print(v ...interface{}) {
	l.Output(INFO, 2, fmt.Sprint(v...))
}
func (l *Logger) Println(v ...interface{}) {
	l.Output(INFO, 2, fmt.Sprintln(v...))
}
func (l *Logger) Debugf(format string, v ...interface{}) {
	if DEBUG < l.level {
		return
	}
	l.Output(DEBUG, 2, fmt.Sprintf(format, v...))
}
func (l *Logger) Debug(v ...interface{}) {
	if DEBUG < l.level {
		return
	}
	l.Output(DEBUG, 2, fmt.Sprintln(v...))
}
func (l *Logger) Infof(format string, v ...interface{}) {
	if INFO < l.level {
		return
	}
	l.Output(INFO, 2, fmt.Sprintf(format, v...))
}
func (l *Logger) Info(v ...interface{}) {
	if INFO < l.level {
		return
	}
	l.Output(INFO, 2, fmt.Sprintln(v...))
}
func (l *Logger) Warnf(format string, v ...interface{}) {
	l.Output(WARN, 2, fmt.Sprintf(format, v...))
}
func (l *Logger) Warn(v ...interface{}) {
	l.Output(WARN, 2, fmt.Sprintln(v...))
}
func (l *Logger) Errorf(format string, v ...interface{}) {
	l.Output(ERROR, 2, fmt.Sprintf(format, v...))
}
func (l *Logger) Error(v ...interface{}) {
	l.Output(ERROR, 2, fmt.Sprintln(v...))
}
func (l *Logger) Fatal(v ...interface{}) {
	l.Output(FATAL, 2, fmt.Sprint(v...))
	os.Exit(1)
}
func (l *Logger) Fatalf(format string, v ...interface{}) {
	l.Output(FATAL, 2, fmt.Sprintf(format, v...))
	os.Exit(1)
}
func (l *Logger) Fatalln(v ...interface{}) {
	l.Output(FATAL, 2, fmt.Sprintln(v...))
	os.Exit(1)
}
func (l *Logger) Panic(v ...interface{}) {
	s := fmt.Sprint(v...)
	l.Output(PANIC, 2, s)
	panic(s)
}