func (l *logger) FatalEnabled() bool {
	return l.isLevelEnabled(fatalLevel)
}
FatalEnabled fatal enabled
package log
import (
	"fmt"
	"io"
	"log"
	"os"
	"runtime"
	"sync"
	"time"
)
const (
	Ldate = log.Ldate
	Llongfile = log.Llongfile
	Lmicroseconds = log.Lmicroseconds
	Lshortfile = log.Lshortfile
	LstdFlags = log.LstdFlags
	Ltime = log.Ltime
)
type (
	Level int
	Type int
)
const (
	fatalLevel = Type(0x1)
	errorLevel = Type(0x2)
	warnLevel  = Type(0x4)
	infoLevel  = Type(0x8)
	debugLevel = Type(0x10)
)
const (
	LogNone = Level(0x0)
	LogFatal = LogNone | Level(fatalLevel)
	LogError = LogFatal | Level(errorLevel)
	LogWarn = LogError | Level(warnLevel)
	LogInfo = LogWarn | Level(infoLevel)
	LogDebug = LogInfo | Level(debugLevel)
	LogAll = LogDebug
)
const (
	formatTimeDay  string = "20060102"
	formatTimeHour string = "2006010215"
)
var defaultLog = new()
func init() {
	SetFlags(Ldate | Ltime | Lmicroseconds | Lmicroseconds)
	SetHighlighting(runtime.GOOS != "windows")
}
func Logger() *log.Logger {
	return defaultLog._log
}
func FatalEnabled() bool {
	return defaultLog.isLevelEnabled(fatalLevel)
}
func ErrorEnabled() bool {
	return defaultLog.isLevelEnabled(errorLevel)
}
func WarnEnabled() bool {
	return defaultLog.isLevelEnabled(warnLevel)
}
func InfoEnabled() bool {
	return defaultLog.isLevelEnabled(infoLevel)
}
func DebugEnabled() bool {
	return defaultLog.isLevelEnabled(debugLevel)
}
func SetLevel(level Level) {
	defaultLog.SetLevel(level)
}
func GetLogLevel() Level {
	return defaultLog.level
}
func SetOutput(out io.Writer) {
	defaultLog.SetOutput(out)
}
func SetOutputByName(path string) error {
	return defaultLog.SetOutputByName(path)
}
func SetFlags(flags int) {
	defaultLog._log.SetFlags(flags)
}
func Info(v ...interface{}) {
	defaultLog.Info(v...)
}
func Infof(format string, v ...interface{}) {
	defaultLog.Infof(format, v...)
}
func Debug(v ...interface{}) {
	defaultLog.Debug(v...)
}
func Debugf(format string, v ...interface{}) {
	defaultLog.Debugf(format, v...)
}
func Warn(v ...interface{}) {
	defaultLog.Warning(v...)
}
func Warnf(format string, v ...interface{}) {
	defaultLog.Warningf(format, v...)
}
func Warning(v ...interface{}) {
	defaultLog.Warning(v...)
}
func Warningf(format string, v ...interface{}) {
	defaultLog.Warningf(format, v...)
}
func Error(v ...interface{}) {
	defaultLog.Error(v...)
}
func Errorf(format string, v ...interface{}) {
	defaultLog.Errorf(format, v...)
}
func Fatal(v ...interface{}) {
	defaultLog.Fatal(v...)
}
func Fatalf(format string, v ...interface{}) {
	defaultLog.Fatalf(format, v...)
}
func SetLevelByString(level string) {
	defaultLog.SetLevelByString(level)
}
func SetHighlighting(highlighting bool) {
	defaultLog.SetHighlighting(highlighting)
}
func SetRotateByDay() {
	defaultLog.SetRotateByDay()
}
func SetRotateByHour() {
	defaultLog.SetRotateByHour()
}
type logger struct {
	_log         *log.Logger
	level        Level
	highlighting bool
	dailyRolling bool
	hourRolling  bool
	fileName  string
	logSuffix string
	fd        *os.File
	lock sync.Mutex
}
func (l *logger) SetHighlighting(highlighting bool) {
	l.highlighting = highlighting
}
func (l *logger) SetLevel(level Level) {
	l.level = level
}
func (l *logger) SetLevelByString(level string) {
	l.level = stringToLogLevel(level)
}
func (l *logger) SetRotateByDay() {
	l.dailyRolling = true
	l.logSuffix = genDayTime(time.Now())
}
func (l *logger) SetRotateByHour() {
	l.hourRolling = true
	l.logSuffix = genHourTime(time.Now())
}
func (l *logger) rotate() error {
	l.lock.Lock()
	defer l.lock.Unlock()
	var suffix string
	if l.dailyRolling {
		suffix = genDayTime(time.Now())
	} else if l.hourRolling {
		suffix = genHourTime(time.Now())
	} else {
		return nil
	}
	if suffix != l.logSuffix {
		err := l.doRotate(suffix)
		if err != nil {
			return err
		}
	}
	return nil
}
func (l *logger) doRotate(suffix string) error {
	l.fd.Close()
	lastFileName := l.fileName + "." + l.logSuffix
	err := os.Rename(l.fileName, lastFileName)
	if err != nil {
		return err
	}
	err = l.SetOutputByName(l.fileName)
	if err != nil {
		return err
	}
	l.logSuffix = suffix
	return nil
}
func (l *logger) SetOutput(out io.Writer) {
	l._log = log.New(out, l._log.Prefix(), l._log.Flags())
}
func (l *logger) SetOutputByName(path string) error {
	f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
	if err != nil {
		log.Fatal(err)
	}
	l.SetOutput(f)
	l.fileName = path
	l.fd = f
	return err
}
func (l *logger) log(t Type, v ...interface{}) {
	if l.level|Level(t) != l.level {
		return
	}
	err := l.rotate()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.Error())
		return
	}
	v1 := make([]interface{}, len(v)+2)
	logStr, logColor := logTypeToString(t)
	if l.highlighting {
		v1[0] = "\033" + logColor + "m[" + logStr + "]"
		copy(v1[1:], v)
		v1[len(v)+1] = "\033[0m"
	} else {
		v1[0] = "[" + logStr + "]"
		copy(v1[1:], v)
		v1[len(v)+1] = ""
	}
	s := fmt.Sprintln(v1...)
	l._log.Output(4, s)
}
func (l *logger) logf(t Type, format string, v ...interface{}) {
	if l.level|Level(t) != l.level {
		return
	}
	err := l.rotate()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.Error())
		return
	}
	logStr, logColor := logTypeToString(t)
	var s string
	if l.highlighting {
		s = "\033" + logColor + "m[" + logStr + "] " + fmt.Sprintf(format, v...) + "\033[0m"
	} else {
		s = "[" + logStr + "] " + fmt.Sprintf(format, v...)
	}
	l._log.Output(4, s)
}