日志库练习
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