package oceanlogger import ( "fmt" "os" "path" "time" ) //定义文件日志对象 type FileLogger struct { lvl LogLevel fileObj *os.File fileName string filepath string fileMaxSize int64 creatTime time.Time } //new文件日志对象 func NewFileLogger(lvLel string, filename, filepath string, filemaxsize int64) *FileLogger { lvl := getLogStruct(lvLel) fl := &FileLogger{ lvl: lvl, filepath: filepath, fileMaxSize: filemaxsize, fileName: filename, creatTime: time.Now(), } fileObj, err := fl.conStructFd() if err != nil { fmt.Printf("new filelogger failed,error:%v", err) } fl.fileObj = fileObj //组装完整结构体对象 return fl } //打开一个文件句柄,用于组成结构体 func (f *FileLogger) conStructFd() (*os.File, error) { fullFilePath := path.Join(f.filepath, f.fileName) fileObj, err := os.OpenFile(fullFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Printf("construct newfilelogger failed,error:%v", err) return nil, err } return fileObj, nil } // 校验文件大小 func (f *FileLogger) checkFileSize(file *os.File) bool { fileInfo, err := file.Stat() if err != nil { fmt.Printf("check filesize func failed,err:%v", err) } if f.fileMaxSize <= fileInfo.Size() { return true } else { return false } } // 校验创建时间 func (f *FileLogger) checkCreateTime(duration time.Duration) bool { now := time.Now() //现在的东八区时间 if now.Sub(f.creatTime) >= duration { return true } else { return false } } // 分割日志文件 func (f *FileLogger) splitFile() error { //根据老日志对象获取信息 fullLogPath := path.Join(f.filepath, f.fileName) timeStr := time.Now().Format("2006150405000") newLogFileName := fmt.Sprintf("%s.bak_%s", fullLogPath, timeStr) //关闭原有的文件句柄 f.close() //重命名原来的文件 err := os.Rename(fullLogPath, newLogFileName) if err != nil { return err } //创建一个新的文件 fileObj, err := os.OpenFile(fullLogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Printf("create newfile failed,error:%v", err) return err } //把新文件的句柄赋值给结构体对象 f.fileObj = fileObj f.creatTime = time.Now() //创建时间 return nil } // 文件日志对象的级别校验 func (f *FileLogger) checkLevel(l LogLevel) bool { if f.lvl <= l { return true } else { return false } } // 总体实现,下面分别调用 func (f *FileLogger) logPrintOverAll(lvl LogLevel, format string, i ...interface{}) { if f.checkLevel(lvl) { msg := fmt.Sprintf(format, i...) funcName, fileName, line, _ := getInfo(3) if f.checkFileSize(f.fileObj) { err := f.splitFile() if err != nil { return } } if f.checkCreateTime(time.Second * 10) { err := f.splitFile() if err != nil { return } } fmt.Fprintf(f.fileObj, "[%s][%s][line:%d,funcname:%s filename:%s] %s\n", getNowTimeStr(), getLogStr(f.lvl), line, funcName, fileName, msg) } } //日志输出实现 func (f *FileLogger) Debug(format string, i ...interface{}) { f.logPrintOverAll(DEBUG, format, i...) } func (f *FileLogger) Info(format string, i ...interface{}) { f.logPrintOverAll(INFO, format, i...) } func (f *FileLogger) Error(format string, i ...interface{}) { f.logPrintOverAll(ERROR, format, i...) } func (f *FileLogger) Fatal(format string, i ...interface{}) { f.logPrintOverAll(FATAL, format, i...) } func (f *FileLogger) close() { err := f.fileObj.Close() if err != nil { fmt.Printf("failed close file!,error:%v", err) } return }