commit ce87fd8c36e58d7c40832ca372e2a7a253891d40 Author: Administrator Date: Tue Apr 9 10:58:40 2024 +0800 日志库练习 diff --git a/base.go b/base.go new file mode 100644 index 0000000..aea0094 --- /dev/null +++ b/base.go @@ -0,0 +1,79 @@ +package oceanlogger + +import ( + "errors" + "path" + "runtime" + "strings" + "time" +) + +//控制台日志对象定义 + +type ConsoleLogger struct { + level LogLevel +} + +//自定义日志级别 + +type LogLevel uint8 + +const ( + Failed LogLevel = 0 + DEBUG LogLevel = iota + INFO + FATAL + ERROR +) + +// 获取当前时间字符串 +func getNowTimeStr() (timestr string) { + timestr = time.Now().Format("2006-01-02 15:04:05") + return + +} + +//通过结构体获取日志级别返回字符串 + +func getLogStr(l LogLevel) string { + switch l { + case DEBUG: + return "DEBUG" + case INFO: + return "INFO" + case ERROR: + return "ERROR" + case FATAL: + return "FATAL" + default: + return "get log string error,check please!" + } +} + +//通过字符串获取结构体日志级别 + +func getLogStruct(s string) LogLevel { + switch strings.ToUpper(s) { + case "DEBUG": + return DEBUG + case "INFO": + return INFO + case "ERROR": + return ERROR + case "FATAL": + return FATAL + default: + return Failed + } +} + +// 获取方法名,文件名,行号函数 +func getInfo(skip int) (funcName, fileName string, line int, err error) { + pc, file, line, ok := runtime.Caller(skip) + if !ok { + return "", "", 0, errors.New("get funcName,File,Line error,please check") + } + funcName = runtime.FuncForPC(pc).Name() + fileName = path.Base(file) + return funcName, fileName, line, nil +} diff --git a/oceanconsolelogger.go b/oceanconsolelogger.go new file mode 100644 index 0000000..5fdb9c4 --- /dev/null +++ b/oceanconsolelogger.go @@ -0,0 +1,48 @@ +package oceanlogger + +import ( + "fmt" +) + +//new日志对象 + +func NewConsoleLogger(s string) ConsoleLogger { + lvl := getLogStruct(s) + return ConsoleLogger{ + level: lvl, + } +} + +// 日志级别判断 +func (c ConsoleLogger) checkLevel(l LogLevel) bool { + if c.level <= l { + return true + } else { + return false + } +} + +// 总体实现,下面分别调用 +func (c ConsoleLogger) logPrintOverAll(lvl LogLevel, format string, i ...interface{}) { + if c.checkLevel(lvl) { + msg := fmt.Sprintf(format, i...) + funcName, fileName, line, _ := getInfo(3) + fmt.Printf("[%s][%s][line:%d,funcname:%s filename:%s] %s\n", getNowTimeStr(), getLogStr(c.level), line, funcName, fileName, msg) + } +} + +//日志输出实现 + +func (c ConsoleLogger) Debug(format string, i ...interface{}) { + c.logPrintOverAll(DEBUG, format, i...) +} + +func (c ConsoleLogger) Info(format string, i ...interface{}) { + c.logPrintOverAll(INFO, format, i...) +} +func (c ConsoleLogger) Error(format string, i ...interface{}) { + c.logPrintOverAll(ERROR, format, i...) +} +func (c ConsoleLogger) Fatal(format string, i ...interface{}) { + c.logPrintOverAll(FATAL, format, i...) +} diff --git a/oceanfilelogger.go b/oceanfilelogger.go new file mode 100644 index 0000000..4a9f0e1 --- /dev/null +++ b/oceanfilelogger.go @@ -0,0 +1,155 @@ +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 +}