基于golang的log库编写一个日志插件,并发写入日志,使用时直接调用里面的公共方法,希望不吝赐教(写完不敢用,怕出问题,因为没有关闭*file)
package utils
import (
"log"
"os"
"sync"
"time"
)
type logfile struct {
date string
fileName string
openFile *os.File
}
type logFiles struct {
rm sync.RWMutex
logf map[string]*logfile
}
type clog struct {
fileName string
msg interface{}
}
var (
eChan = make(chan clog, 100)
nChan = make(chan clog, 100)
wChan = make(chan clog, 100)
loger logFiles
)
const flag = log.Llongfile + log.Ltime
func init() {
logmp := make(map[string]*logfile, 3)
loger.logf = logmp
go writerLog()
}
func getOpenFile(fileName string) *os.File {
currentDate := time.Now().Format("2006-01-03")
if v, ok := loger.logf[fileName]; ok {
if v.date != currentDate {
loger.rm.Lock()
newOpen, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
log.Fatal(err)
}
loger.logf[fileName] = &logfile{
date: currentDate,
fileName: fileName,
openFile: newOpen,
}
loger.rm.Unlock()
return newOpen
} else {
return v.openFile
}
}
loger.rm.Lock()
newOpen, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
log.Fatal(err)
}
loger.logf[fileName] = &logfile{
date: currentDate,
fileName: fileName,
openFile: newOpen,
}
loger.rm.Unlock()
return newOpen
}
func writerLog() {
for {
select {
case l := <-eChan:
file := getOpenFile(l.fileName)
logger := log.New(file, "", flag)
logger.Println(l.msg)
file.Sync()
case w := <-wChan:
file := getOpenFile(w.fileName)
logger := log.New(file, "", flag)
logger.Println(w.msg)
file.Sync()
case n := <-nChan:
file := getOpenFile(n.fileName)
logger := log.New(file, "", flag)
logger.Println(n.msg)
file.Sync()
}
}
}
func LogWarning(msg interface{}) {
wChan <- clog{
fileName: "logs/warning" + time.Now().Format("2006-01-03") + ".log",
msg: msg,
}
}
func LogError(msg interface{}) {
eChan <- clog{
fileName: "logs/err" + time.Now().Format("2006-01-03") + ".log",
msg: msg,
}
}
func LogNote(msg interface{}) {
nChan <- clog{
fileName: "logs/note" + time.Now().Format("2006-01-03") + ".log",
msg: msg,
}
}