日志库练习
commit
ce87fd8c36
|
@ -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
|
||||||
|
}
|
|
@ -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...)
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue