保存一個別人的golang 日誌庫

package loggergit


import (github

"fmt"測試

"log"spa

"os"debug

"runtime"日誌

"strconv"code

"sync"orm

"time"string

)it


const (

_VER string = "1.0.0"

)


type LEVEL int32


var logLevel LEVEL = 1

var maxFileSize int64

var maxFileCount int32

var dailyRolling bool = true

var consoleAppender bool = true

var RollingFile bool = false

var logObj *_FILE


const DATEFORMAT = "2006-01-02"


type UNIT int64


const (

_       = iota

KB UNIT = 1 << (iota * 10)

MB

GB

TB

)


const (

ALL LEVEL = iota

DEBUG

INFO

WARN

ERROR

FATAL

OFF

)


type _FILE struct {

dir      string

filename string

_suffix  int

isCover  bool

_date    *time.Time

mu       *sync.RWMutex

logfile  *os.File

lg       *log.Logger

}


func SetConsole(isConsole bool) {

consoleAppender = isConsole

}


func SetLevel(_level LEVEL) {

logLevel = _level

}


func SetRollingFile(fileDir, fileName string, maxNumber int32, maxSize int64, _unit UNIT) {

maxFileCount = maxNumber

maxFileSize = maxSize * int64(_unit)

RollingFile = true

dailyRolling = false

logObj = &_FILE{dir: fileDir, filename: fileName, isCover: false, mu: new(sync.RWMutex)}

logObj.mu.Lock()

defer logObj.mu.Unlock()

for i := 1; i <= int(maxNumber); i++ {

if isExist(fileDir + "/" + fileName + "." + strconv.Itoa(i)) {

logObj._suffix = i

} else {

break

}

}

if !logObj.isMustRename() {

logObj.logfile, _ = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0)

logObj.lg = log.New(logObj.logfile, "\n", log.Ldate|log.Ltime|log.Lshortfile)

} else {

logObj.rename()

}

go fileMonitor()

}


func SetRollingDaily(fileDir, fileName string) {

RollingFile = false

dailyRolling = true

t, _ := time.Parse(DATEFORMAT, time.Now().Format(DATEFORMAT))

logObj = &_FILE{dir: fileDir, filename: fileName, _date: &t, isCover: false, mu: new(sync.RWMutex)}

logObj.mu.Lock()

defer logObj.mu.Unlock()


if !logObj.isMustRename() {

logObj.logfile, _ = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0)

logObj.lg = log.New(logObj.logfile, "\n", log.Ldate|log.Ltime|log.Lshortfile)

} else {

logObj.rename()

}

}


func console(s ...interface{}) {

if consoleAppender {

_, file, line, _ := runtime.Caller(2)

short := file

for i := len(file) - 1; i > 0; i-- {

if file[i] == '/' {

short = file[i+1:]

break

}

}

file = short

log.Println(file+":"+strconv.Itoa(line), s)

}

}


func catchError() {

if err := recover(); err != nil {

log.Println("err", err)

}

}


func Debug(v ...interface{}) {

if dailyRolling {

fileCheck()

}

defer catchError()

logObj.mu.RLock()

defer logObj.mu.RUnlock()


if logLevel <= DEBUG {

logObj.lg.Output(2, fmt.Sprintln("debug", v))

console("debug", v)

}

}

func Info(v ...interface{}) {

if dailyRolling {

fileCheck()

}

defer catchError()

logObj.mu.RLock()

defer logObj.mu.RUnlock()

if logLevel <= INFO {

logObj.lg.Output(2, fmt.Sprintln("info", v))

console("info", v)

}

}

func Warn(v ...interface{}) {

if dailyRolling {

fileCheck()

}

defer catchError()

logObj.mu.RLock()

defer logObj.mu.RUnlock()

if logLevel <= WARN {

logObj.lg.Output(2, fmt.Sprintln("warn", v))

console("warn", v)

}

}

func Error(v ...interface{}) {

if dailyRolling {

fileCheck()

}

defer catchError()

logObj.mu.RLock()

defer logObj.mu.RUnlock()

if logLevel <= ERROR {

logObj.lg.Output(2, fmt.Sprintln("error", v))

console("error", v)

}

}

func Fatal(v ...interface{}) {

if dailyRolling {

fileCheck()

}

defer catchError()

logObj.mu.RLock()

defer logObj.mu.RUnlock()

if logLevel <= FATAL {

logObj.lg.Output(2, fmt.Sprintln("fatal", v))

console("fatal", v)

}

}


func (f *_FILE) isMustRename() bool {

if dailyRolling {

t, _ := time.Parse(DATEFORMAT, time.Now().Format(DATEFORMAT))

if t.After(*f._date) {

return true

}

} else {

if maxFileCount > 1 {

if fileSize(f.dir+"/"+f.filename) >= maxFileSize {

return true

}

}

}

return false

}


func (f *_FILE) rename() {

if dailyRolling {

fn := f.dir + "/" + f.filename + "." + f._date.Format(DATEFORMAT)

if !isExist(fn) && f.isMustRename() {

if f.logfile != nil {

f.logfile.Close()

}

err := os.Rename(f.dir+"/"+f.filename, fn)

if err != nil {

f.lg.Println("rename err", err.Error())

}

t, _ := time.Parse(DATEFORMAT, time.Now().Format(DATEFORMAT))

f._date = &t

f.logfile, _ = os.Create(f.dir + "/" + f.filename)

f.lg = log.New(logObj.logfile, "\n", log.Ldate|log.Ltime|log.Lshortfile)

}

} else {

f.coverNextOne()

}

}


func (f *_FILE) nextSuffix() int {

return int(f._suffix%int(maxFileCount) + 1)

}


func (f *_FILE) coverNextOne() {

f._suffix = f.nextSuffix()

if f.logfile != nil {

f.logfile.Close()

}

if isExist(f.dir + "/" + f.filename + "." + strconv.Itoa(int(f._suffix))) {

os.Remove(f.dir + "/" + f.filename + "." + strconv.Itoa(int(f._suffix)))

}

os.Rename(f.dir+"/"+f.filename, f.dir+"/"+f.filename+"."+strconv.Itoa(int(f._suffix)))

f.logfile, _ = os.Create(f.dir + "/" + f.filename)

f.lg = log.New(logObj.logfile, "\n", log.Ldate|log.Ltime|log.Lshortfile)

}


func fileSize(file string) int64 {

fmt.Println("fileSize", file)

f, e := os.Stat(file)

if e != nil {

fmt.Println(e.Error())

return 0

}

return f.Size()

}


func isExist(path string) bool {

_, err := os.Stat(path)

return err == nil || os.IsExist(err)

}


func fileMonitor() {

timer := time.NewTicker(1 * time.Second)

for {

select {

case <-timer.C:

fileCheck()

}

}

}


func fileCheck() {

defer func() {

if err := recover(); err != nil {

log.Println(err)

}

}()

if logObj != nil && logObj.isMustRename() {

logObj.mu.Lock()

defer logObj.mu.Unlock()

logObj.rename()

}

}


使用方法

package exampleimport ( "github.com/donnie4w/go-logger/logger" "runtime" "strconv" "testing" "time")func log(i int) { logger.Debug("Debug>>>>>>>>>>>>>>>>>>>>>>" + strconv.Itoa(i)) logger.Info("Info>>>>>>>>>>>>>>>>>>>>>>>>>" + strconv.Itoa(i)) logger.Warn("Warn>>>>>>>>>>>>>>>>>>>>>>>>>" + strconv.Itoa(i)) logger.Error("Error>>>>>>>>>>>>>>>>>>>>>>>>>" + strconv.Itoa(i)) logger.Fatal("Fatal>>>>>>>>>>>>>>>>>>>>>>>>>" + strconv.Itoa(i))}func Test(t *testing.T) { runtime.GOMAXPROCS(runtime.NumCPU()) //指定是否控制檯打印,默認爲true logger.SetConsole(true) //指定日誌文件備份方式爲文件大小的方式 //第一個參數爲日誌文件存放目錄 //第二個參數爲日誌文件命名 //第三個參數爲備份文件最大數量 //第四個參數爲備份文件大小 //第五個參數爲文件大小的單位 //logger.SetRollingFile("d:/logtest", "test.log", 10, 5, logger.KB) //指定日誌文件備份方式爲日期的方式 //第一個參數爲日誌文件存放目錄 //第二個參數爲日誌文件命名 logger.SetRollingDaily("d:/logtest", "test.log") //指定日誌級別  ALL,DEBUG,INFO,WARN,ERROR,FATAL,OFF 級別由低到高 //通常習慣是測試階段爲debug,生成環境爲info以上 logger.SetLevel(logger.ERROR) for i := 10000; i > 0; i-- { go log(i) time.Sleep(1000 * time.Millisecond) } time.Sleep(15 * time.Second)}

相關文章
相關標籤/搜索