保存一个别人的golang 日志库

984195889 · · 5402 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

package logger


import (

"fmt"

"log"

"os"

"runtime"

"strconv"

"sync"

"time"

)


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 example

import (
"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)
}




有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:984195889

查看原文:保存一个别人的golang 日志库

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

5402 次点击  ∙  1 赞  
加入收藏 微博
2 回复  |  直到 2000-01-01 00:00:00
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传