日志库练习

master
Administrator 2024-04-09 10:58:40 +08:00
commit ce87fd8c36
3 changed files with 282 additions and 0 deletions

79
base.go Normal file
View File

@ -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
}

48
oceanconsolelogger.go Normal file
View File

@ -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...)
}

155
oceanfilelogger.go Normal file
View File

@ -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
}