diff --git a/logger/logger.go b/logger/logger.go index 09bda8e..9d76e3a 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -1,32 +1,19 @@ package logger -import ( - "fmt" - "log" - "os" - "runtime" - "strconv" - "sync" - "time" -) +// "log" const ( - _VER string = "1.0.2" + //go-logger version + _VER string = "1.0.3" ) type LEVEL int32 +type UNIT int64 +type _ROLLTYPE int //dailyRolling ,rollingFile -var logLevel LEVEL = 1 -var maxFileSize int64 -var maxFileCount int32 -var dailyRolling bool = true -var consoleAppender bool = true -var RollingFile bool = false -var logObj *_FILE - -const DATEFORMAT = "2006-01-02" +const _DATEFORMAT = "2006-01-02" -type UNIT int64 +var logLevel LEVEL = 1 const ( _ = iota @@ -46,273 +33,254 @@ const ( OFF ) -type _FILE struct { - dir string - filename string - _suffix int - isCover bool - _date *time.Time - mu *sync.RWMutex - logfile *os.File - lg *log.Logger -} +const ( + _DAILY _ROLLTYPE = iota + _ROLLFILE +) func SetConsole(isConsole bool) { - consoleAppender = isConsole + defaultlog.setConsole(isConsole) } func SetLevel(_level LEVEL) { - logLevel = _level + defaultlog.setLevel(_level) } -func SetRollingFile(fileDir, fileName string, maxNumber int32, maxSize int64, _unit UNIT) { - maxFileCount = maxNumber - maxFileSize = maxSize * int64(_unit) - RollingFile = true - dailyRolling = false - mkdirlog(fileDir) - logObj = &_FILE{dir: fileDir, filename: fileName, isCover: false, mu: new(sync.RWMutex)} - logObj.mu.Lock() - defer logObj.mu.Unlock() - for i := 1; i <= int(maxNumber); i++ { - if isExist(fileDir + "/" + fileName + "." + strconv.Itoa(i)) { - logObj._suffix = i - } else { - break - } - } - if !logObj.isMustRename() { - logObj.logfile, _ = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) - logObj.lg = log.New(logObj.logfile, "", log.Ldate|log.Ltime|log.Lshortfile) - } else { - logObj.rename() - } - go fileMonitor() +func SetFormat(logFormat string) { + defaultlog.setFormat(logFormat) } -func SetRollingDaily(fileDir, fileName string) { - RollingFile = false - dailyRolling = true - t, _ := time.Parse(DATEFORMAT, time.Now().Format(DATEFORMAT)) - mkdirlog(fileDir) - logObj = &_FILE{dir: fileDir, filename: fileName, _date: &t, isCover: false, mu: new(sync.RWMutex)} - logObj.mu.Lock() - defer logObj.mu.Unlock() - - if !logObj.isMustRename() { - logObj.logfile, _ = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) - logObj.lg = log.New(logObj.logfile, "", log.Ldate|log.Ltime|log.Lshortfile) - } else { - logObj.rename() - } +func SetRollingFile(fileDir, fileName string, maxNumber int32, maxSize int64, _unit UNIT) { + // maxFileCount = maxNumber + // maxFileSize = maxSize * int64(_unit) + // RollingFile = true + // dailyRolling = false + // mkdirlog(fileDir) + // logObj = &_FILE{dir: fileDir, filename: fileName, isCover: false, mu: new(sync.RWMutex)} + // logObj.mu.Lock() + // defer logObj.mu.Unlock() + // for i := 1; i <= int(maxNumber); i++ { + // if isExist(fileDir + "/" + fileName + "." + strconv.Itoa(i)) { + // logObj._suffix = i + // } else { + // break + // } + // } + // if !logObj.isMustRename() { + // logObj.logfile, _ = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) + // logObj.lg = log.New(logObj.logfile, "", log.Ldate|log.Ltime|log.Lshortfile) + // } else { + // logObj.rename() + // } + // go fileMonitor() + defaultlog.setRollingFile(fileDir, fileName, maxNumber, maxSize, _unit) } -func mkdirlog(dir string) (e error) { - _, er := os.Stat(dir) - b := er == nil || os.IsExist(er) - if !b { - if err := os.MkdirAll(dir, 0666); err != nil { - if os.IsPermission(err) { - fmt.Println("create dir error:", err.Error()) - e = err - } - } - } - return +func SetRollingDaily(fileDir, fileName string) { + // RollingFile = false + // dailyRolling = true + // t, _ := time.Parse(_DATEFORMAT, time.Now().Format(_DATEFORMAT)) + // mkdirlog(fileDir) + // logObj = &_FILE{dir: fileDir, filename: fileName, _date: &t, isCover: false, mu: new(sync.RWMutex)} + // logObj.mu.Lock() + // defer logObj.mu.Unlock() + // if !logObj.isMustRename() { + // logObj.logfile, _ = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) + // logObj.lg = log.New(logObj.logfile, "", log.Ldate|log.Ltime|log.Lshortfile) + // } else { + // logObj.rename() + // } + defaultlog.setRollingDaily(fileDir, fileName) } -func console(s ...interface{}) { - if consoleAppender { - _, file, line, _ := runtime.Caller(2) - short := file - for i := len(file) - 1; i > 0; i-- { - if file[i] == '/' { - short = file[i+1:] - break - } - } - file = short - log.Println(file, strconv.Itoa(line), s) - } -} +//func console(s ...interface{}) { +// if consoleAppender { +// _, file, line, _ := runtime.Caller(2) +// short := file +// for i := len(file) - 1; i > 0; i-- { +// if file[i] == '/' { +// short = file[i+1:] +// break +// } +// } +// file = short +// log.Println(file, strconv.Itoa(line), s) +// } +//} -func catchError() { - if err := recover(); err != nil { - log.Println("err", err) - } -} +//func catchError() { +// if err := recover(); err != nil { +// log.Println("err", err) +// } +//} func Debug(v ...interface{}) { - if dailyRolling { - fileCheck() - } - defer catchError() - if logObj != nil { - logObj.mu.RLock() - defer logObj.mu.RUnlock() - } - - if logLevel <= DEBUG { - if logObj != nil { - logObj.lg.Output(2, fmt.Sprintln("debug", v)) - } - console("debug", v) - } + // if dailyRolling { + // fileCheck() + // } + // defer catchError() + // if logObj != nil { + // logObj.mu.RLock() + // defer logObj.mu.RUnlock() + // } + // if logLevel <= DEBUG { + // if logObj != nil { + // logObj.lg.Output(2, fmt.Sprintln("debug", v)) + // } + // console("debug", v) + // } + defaultlog.debug(v...) } func Info(v ...interface{}) { - if dailyRolling { - fileCheck() - } - defer catchError() - if logObj != nil { - logObj.mu.RLock() - defer logObj.mu.RUnlock() - } - if logLevel <= INFO { - if logObj != nil { - logObj.lg.Output(2, fmt.Sprintln("info", v)) - } - console("info", v) - } + // if dailyRolling { + // fileCheck() + // } + // defer catchError() + // if logObj != nil { + // logObj.mu.RLock() + // defer logObj.mu.RUnlock() + // } + // if logLevel <= INFO { + // if logObj != nil { + // if format == "" { + // logObj.lg.Output(2, fmt.Sprintln("info", v)) + // } else { + // logObj.lg.Output(2, fmt.Sprintf(format, v...)) + // } + // } + // console("info", v) + // } + defaultlog.info(v...) } func Warn(v ...interface{}) { - if dailyRolling { - fileCheck() - } - defer catchError() - if logObj != nil { - logObj.mu.RLock() - defer logObj.mu.RUnlock() - } - - if logLevel <= WARN { - if logObj != nil { - logObj.lg.Output(2, fmt.Sprintln("warn", v)) - } - console("warn", v) - } + // if dailyRolling { + // fileCheck() + // } + // defer catchError() + // if logObj != nil { + // logObj.mu.RLock() + // defer logObj.mu.RUnlock() + // } + // if logLevel <= WARN { + // if logObj != nil { + // logObj.lg.Output(2, fmt.Sprintln("warn", v)) + // } + // console("warn", v) + // } + defaultlog.warn(v...) } func Error(v ...interface{}) { - if dailyRolling { - fileCheck() - } - defer catchError() - if logObj != nil { - logObj.mu.RLock() - defer logObj.mu.RUnlock() - } - if logLevel <= ERROR { - if logObj != nil { - logObj.lg.Output(2, fmt.Sprintln("error", v)) - } - console("error", v) - } + // if dailyRolling { + // fileCheck() + // } + // defer catchError() + // if logObj != nil { + // logObj.mu.RLock() + // defer logObj.mu.RUnlock() + // } + // if logLevel <= ERROR { + // if logObj != nil { + // logObj.lg.Output(2, fmt.Sprintln("error", v)) + // } + // console("error", v) + // } + defaultlog.error(v...) } func Fatal(v ...interface{}) { - if dailyRolling { - fileCheck() - } - defer catchError() - if logObj != nil { - logObj.mu.RLock() - defer logObj.mu.RUnlock() - } - if logLevel <= FATAL { - if logObj != nil { - logObj.lg.Output(2, fmt.Sprintln("fatal", v)) - } - console("fatal", v) - } + // if dailyRolling { + // fileCheck() + // } + // defer catchError() + // if logObj != nil { + // logObj.mu.RLock() + // defer logObj.mu.RUnlock() + // } + // if logLevel <= FATAL { + // if logObj != nil { + // logObj.lg.Output(2, fmt.Sprintln("fatal", v)) + // } + // console("fatal", v) + // } + defaultlog.fatal(v...) } -func (f *_FILE) isMustRename() bool { - if dailyRolling { - t, _ := time.Parse(DATEFORMAT, time.Now().Format(DATEFORMAT)) - if t.After(*f._date) { - return true - } - } else { - if maxFileCount > 1 { - if fileSize(f.dir+"/"+f.filename) >= maxFileSize { - return true - } - } - } - return false +func SetLevelFile(level LEVEL, dir, fileName string) { + defaultlog.setLevelFile(level, dir, fileName) } -func (f *_FILE) rename() { - if dailyRolling { - fn := f.dir + "/" + f.filename + "." + f._date.Format(DATEFORMAT) - if !isExist(fn) && f.isMustRename() { - if f.logfile != nil { - f.logfile.Close() - } - err := os.Rename(f.dir+"/"+f.filename, fn) - if err != nil { - f.lg.Println("rename err", err.Error()) - } - t, _ := time.Parse(DATEFORMAT, time.Now().Format(DATEFORMAT)) - f._date = &t - f.logfile, _ = os.Create(f.dir + "/" + f.filename) - f.lg = log.New(logObj.logfile, "\n", log.Ldate|log.Ltime|log.Lshortfile) - } - } else { - f.coverNextOne() - } -} +//func isMustRename() bool { +// if dailyRolling { +// t, _ := time.Parse(_DATEFORMAT, time.Now().Format(_DATEFORMAT)) +// if t.After(*f._date) { +// return true +// } +// } else { +// if maxFileCount > 1 { +// if fileSize(f.dir+"/"+f.filename) >= maxFileSize { +// return true +// } +// } +// } +// return false +//} -func (f *_FILE) nextSuffix() int { - return int(f._suffix%int(maxFileCount) + 1) -} +//func rename() { +// if dailyRolling { +// fn := f.dir + "/" + f.filename + "." + f._date.Format(_DATEFORMAT) +// if !isExist(fn) && f.isMustRename() { +// if f.logfile != nil { +// f.logfile.Close() +// } +// err := os.Rename(f.dir+"/"+f.filename, fn) +// if err != nil { +// f.lg.Println("rename err", err.Error()) +// } +// t, _ := time.Parse(_DATEFORMAT, time.Now().Format(_DATEFORMAT)) +// f._date = &t +// f.logfile, _ = os.Create(f.dir + "/" + f.filename) +// f.lg = log.New(logObj.logfile, "\n", log.Ldate|log.Ltime|log.Lshortfile) +// } +// } else { +// f.coverNextOne() +// } +//} -func (f *_FILE) coverNextOne() { - f._suffix = f.nextSuffix() - if f.logfile != nil { - f.logfile.Close() - } - if isExist(f.dir + "/" + f.filename + "." + strconv.Itoa(int(f._suffix))) { - os.Remove(f.dir + "/" + f.filename + "." + strconv.Itoa(int(f._suffix))) - } - os.Rename(f.dir+"/"+f.filename, f.dir+"/"+f.filename+"."+strconv.Itoa(int(f._suffix))) - f.logfile, _ = os.Create(f.dir + "/" + f.filename) - f.lg = log.New(logObj.logfile, "\n", log.Ldate|log.Ltime|log.Lshortfile) -} - -func fileSize(file string) int64 { - fmt.Println("fileSize", file) - f, e := os.Stat(file) - if e != nil { - fmt.Println(e.Error()) - return 0 - } - return f.Size() -} +//func nextSuffix() int { +// return int(f._suffix%int(maxFileCount) + 1) +//} -func isExist(path string) bool { - _, err := os.Stat(path) - return err == nil || os.IsExist(err) -} +//func coverNextOne() { +// f._suffix = f.nextSuffix() +// if f.logfile != nil { +// f.logfile.Close() +// } +// if isExist(f.dir + "/" + f.filename + "." + strconv.Itoa(int(f._suffix))) { +// os.Remove(f.dir + "/" + f.filename + "." + strconv.Itoa(int(f._suffix))) +// } +// os.Rename(f.dir+"/"+f.filename, f.dir+"/"+f.filename+"."+strconv.Itoa(int(f._suffix))) +// f.logfile, _ = os.Create(f.dir + "/" + f.filename) +// f.lg = log.New(logObj.logfile, "\n", log.Ldate|log.Ltime|log.Lshortfile) +//} -func fileMonitor() { - timer := time.NewTicker(1 * time.Second) - for { - select { - case <-timer.C: - fileCheck() - } - } -} +//func fileMonitor() { +// timer := time.NewTicker(1 * time.Second) +// for { +// select { +// case <-timer.C: +// fileCheck() +// } +// } +//} -func fileCheck() { - defer func() { - if err := recover(); err != nil { - log.Println(err) - } - }() - if logObj != nil && logObj.isMustRename() { - logObj.mu.Lock() - defer logObj.mu.Unlock() - logObj.rename() - } -} +//func fileCheck() { +// defer func() { +// if err := recover(); err != nil { +// log.Println(err) +// } +// }() +// if logObj != nil && logObj.isMustRename() { +// logObj.mu.Lock() +// defer logObj.mu.Unlock() +// logObj.rename() +// } +//} diff --git a/logger/logw.go b/logger/logw.go new file mode 100644 index 0000000..59f9ca9 --- /dev/null +++ b/logger/logw.go @@ -0,0 +1,412 @@ +package logger + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "log" + "os" + "runtime" + "runtime/debug" + "strconv" + "sync" + "sync/atomic" + "time" +) + +var defaultlog *logBean = getdefaultLogger() +var skip int = 4 + +type logger struct { + lb *logBean +} + +func (this *logger) SetConsole(isConsole bool) { + this.lb.setConsole(isConsole) +} + +func (this *logger) SetLevel(_level LEVEL) { + this.lb.setLevel(_level) +} + +func (this *logger) SetFormat(logFormat string) { + this.lb.setFormat(logFormat) +} + +func (this *logger) SetRollingFile(fileDir, fileName string, maxNumber int32, maxSize int64, _unit UNIT) { + this.lb.setRollingFile(fileDir, fileName, maxNumber, maxSize, _unit) +} + +func (this *logger) SetRollingDaily(fileDir, fileName string) { + this.lb.setRollingDaily(fileDir, fileName) +} + +func (this *logger) Debug(v ...interface{}) { + this.lb.debug(v...) +} +func (this *logger) Info(v ...interface{}) { + this.lb.info(v...) +} +func (this *logger) Warn(v ...interface{}) { + this.lb.warn(v...) +} +func (this *logger) Error(v ...interface{}) { + this.lb.error(v...) +} +func (this *logger) Fatal(v ...interface{}) { + this.lb.fatal(v...) +} + +func (this *logger) SetLevelFile(level LEVEL, dir, fileName string) { + this.lb.setLevelFile(level, dir, fileName) +} + +type logBean struct { + mu *sync.Mutex + logLevel LEVEL + maxFileSize int64 + maxFileCount int32 + consoleAppender bool + rolltype _ROLLTYPE + format string + id string + d, i, w, e, f string //id +} + +type fileBeanFactory struct { + fbs map[string]*fileBean + mu *sync.RWMutex +} + +var fbf = &fileBeanFactory{fbs: make(map[string]*fileBean, 0), mu: new(sync.RWMutex)} + +func (this *fileBeanFactory) add(dir, filename string, _suffix int, maxsize int64, maxfileCount int32) { + this.mu.Lock() + defer this.mu.Unlock() + id := md5str(fmt.Sprint(dir, filename)) + if _, ok := this.fbs[id]; !ok { + this.fbs[id] = newFileBean(dir, filename, _suffix, maxsize, maxfileCount) + } +} + +func (this *fileBeanFactory) get(id string) *fileBean { + this.mu.RLock() + defer this.mu.RUnlock() + return this.fbs[id] +} + +type fileBean struct { + id string + dir string + filename string + _suffix int + _date *time.Time + mu *sync.RWMutex + logfile *os.File + lg *log.Logger + filesize int64 + maxFileSize int64 + maxFileCount int32 +} + +func GetLogger() (l *logger) { + l = new(logger) + l.lb = getdefaultLogger() + return +} + +func getdefaultLogger() (lb *logBean) { + lb = &logBean{} + lb.mu = new(sync.Mutex) + return +} + +func (this *logBean) setConsole(isConsole bool) { + this.consoleAppender = isConsole +} + +func (this *logBean) setLevelFile(level LEVEL, dir, fileName string) { + key := md5str(fmt.Sprint(dir, fileName)) + switch level { + case DEBUG: + this.d = key + case INFO: + this.i = key + case WARN: + this.w = key + case ERROR: + this.e = key + case FATAL: + this.f = key + default: + return + } + var _suffix = 0 + if this.maxFileCount < 1<<31-1 { + for i := 1; i < int(this.maxFileCount); i++ { + if isExist(dir + "/" + fileName + "." + strconv.Itoa(i)) { + _suffix = i + } else { + break + } + } + } + fbf.add(dir, fileName, _suffix, this.maxFileSize, this.maxFileCount) +} + +func (this *logBean) setLevel(_level LEVEL) { + this.logLevel = _level +} + +func (this *logBean) setFormat(logFormat string) { + this.format = logFormat +} + +func (this *logBean) setRollingFile(fileDir, fileName string, maxNumber int32, maxSize int64, _unit UNIT) { + this.mu.Lock() + defer this.mu.Unlock() + if maxNumber > 0 { + this.maxFileCount = maxNumber + } else { + this.maxFileCount = 1<<31 - 1 + } + this.maxFileSize = maxSize * int64(_unit) + this.rolltype = _ROLLFILE + mkdirlog(fileDir) + var _suffix = 0 + for i := 1; i < int(maxNumber); i++ { + if isExist(fileDir + "/" + fileName + "." + strconv.Itoa(i)) { + _suffix = i + } else { + break + } + } + this.id = md5str(fmt.Sprint(fileDir, fileName)) + fbf.add(fileDir, fileName, _suffix, this.maxFileSize, this.maxFileCount) +} + +func (this *logBean) setRollingDaily(fileDir, fileName string) { + this.rolltype = _DAILY + mkdirlog(fileDir) + this.id = md5str(fmt.Sprint(fileDir, fileName)) + fbf.add(fileDir, fileName, 0, 0, 0) +} + +func (this *logBean) console(v ...interface{}) { + s := fmt.Sprint(v...) + if this.consoleAppender { + _, file, line, _ := runtime.Caller(skip) + short := file + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + short = file[i+1:] + break + } + } + file = short + if this.format == "" { + log.Println(file, strconv.Itoa(line), s) + } else { + vs := make([]interface{}, 0) + vs = append(vs, file) + vs = append(vs, strconv.Itoa(line)) + for _, vv := range v { + vs = append(vs, vv) + } + log.Printf(fmt.Sprint("%s %s ", this.format, "\n"), vs...) + } + } +} + +func (this *logBean) log(level string, v ...interface{}) { + defer catchError() + s := fmt.Sprint(v...) + length := len([]byte(s)) + var lg *fileBean = fbf.get(this.id) + var _level = ALL + switch level { + case "debug": + if this.d != "" { + lg = fbf.get(this.d) + } + _level = DEBUG + case "info": + if this.i != "" { + lg = fbf.get(this.i) + } + _level = INFO + case "warn": + if this.w != "" { + lg = fbf.get(this.w) + } + _level = WARN + case "error": + if this.e != "" { + lg = fbf.get(this.e) + } + _level = ERROR + case "fatal": + if this.f != "" { + lg = fbf.get(this.f) + } + _level = FATAL + } + this.fileCheck(lg) + lg.addsize(int64(length)) + if this.logLevel <= _level { + if lg != nil { + if this.format == "" { + lg.write(level, s) + } else { + lg.writef(this.format, v...) + } + } + this.console(v...) + } +} + +func (this *logBean) debug(v ...interface{}) { + this.log("debug", v...) +} +func (this *logBean) info(v ...interface{}) { + this.log("info", v...) +} +func (this *logBean) warn(v ...interface{}) { + this.log("warn", v...) +} +func (this *logBean) error(v ...interface{}) { + this.log("error", v...) +} +func (this *logBean) fatal(v ...interface{}) { + this.log("fatal", v...) +} + +func (this *logBean) fileCheck(fb *fileBean) { + defer catchError() + if this.isMustRename(fb) { + this.mu.Lock() + defer this.mu.Unlock() + if this.isMustRename(fb) { + fb.rename(this.rolltype) + } + } +} + +//-------------------------------------------------------------------------------- + +func (this *logBean) isMustRename(fb *fileBean) bool { + switch this.rolltype { + case _DAILY: + t, _ := time.Parse(_DATEFORMAT, time.Now().Format(_DATEFORMAT)) + if t.After(*fb._date) { + return true + } + case _ROLLFILE: + return fb.isOverSize() + } + return false +} + +func (this *fileBean) nextSuffix() int { + return int(this._suffix%int(this.maxFileCount) + 1) +} + +func newFileBean(fileDir, fileName string, _suffix int, maxSize int64, maxfileCount int32) (fb *fileBean) { + t, _ := time.Parse(_DATEFORMAT, time.Now().Format(_DATEFORMAT)) + fb = &fileBean{dir: fileDir, filename: fileName, _date: &t, mu: new(sync.RWMutex)} + fb.logfile, _ = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) + fb.lg = log.New(fb.logfile, "", log.Ldate|log.Ltime|log.Lshortfile) + fb._suffix = _suffix + fb.maxFileSize = maxSize + fb.maxFileCount = maxfileCount + fb.filesize = fileSize(fileDir + "/" + fileName) + fb._date = &t + return +} + +func (this *fileBean) rename(rolltype _ROLLTYPE) { + this.mu.Lock() + defer this.mu.Unlock() + this.close() + nextfilename := "" + switch rolltype { + case _DAILY: + nextfilename = fmt.Sprint(this.dir, "/", this.filename, ".", this._date.Format(_DATEFORMAT)) + case _ROLLFILE: + nextfilename = fmt.Sprint(this.dir, "/", this.filename, ".", this.nextSuffix()) + this._suffix = this.nextSuffix() + } + if isExist(nextfilename) { + os.Remove(nextfilename) + } + os.Rename(this.dir+"/"+this.filename, nextfilename) + this.logfile, _ = os.OpenFile(this.dir+"/"+this.filename, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) + this.lg = log.New(this.logfile, "", log.Ldate|log.Ltime|log.Lshortfile) + this.filesize = fileSize(this.dir + "/" + this.filename) +} + +func (this *fileBean) addsize(size int64) { + atomic.AddInt64(&this.filesize, size) +} + +func (this *fileBean) write(level string, v ...interface{}) { + this.mu.RLock() + defer this.mu.RUnlock() + s := fmt.Sprint(v...) + this.lg.Output(skip+1, fmt.Sprintln(level, s)) +} + +func (this *fileBean) writef(format string, v ...interface{}) { + this.mu.RLock() + defer this.mu.RUnlock() + this.lg.Output(skip+1, fmt.Sprintf(format, v...)) +} + +func (this *fileBean) isOverSize() bool { + return this.filesize >= this.maxFileSize +} + +func (this *fileBean) close() { + this.logfile.Close() +} + +//----------------------------------------------------------------------------------------------- + +func mkdirlog(dir string) (e error) { + _, er := os.Stat(dir) + b := er == nil || os.IsExist(er) + if !b { + if err := os.MkdirAll(dir, 0666); err != nil { + if os.IsPermission(err) { + e = err + } + } + } + return +} + +func fileSize(file string) int64 { + f, e := os.Stat(file) + if e != nil { + fmt.Println(e.Error()) + return 0 + } + return f.Size() +} + +func isExist(path string) bool { + _, err := os.Stat(path) + return err == nil || os.IsExist(err) +} + +func md5str(s string) string { + m := md5.New() + m.Write([]byte(s)) + return hex.EncodeToString(m.Sum(nil)) +} + +func catchError() { + if err := recover(); err != nil { + fmt.Println(string(debug.Stack())) + } +}