Files
openp2p/core/log.go
2022-11-03 11:07:32 +08:00

165 lines
3.3 KiB
Go

package openp2p
import (
"log"
"os"
"runtime"
"sync"
"time"
)
type LogLevel int
var gLog *logger
const (
LvDEBUG LogLevel = iota
LvINFO
LvWARN
LvERROR
)
var (
logFileNames map[LogLevel]string
loglevel map[LogLevel]string
)
func init() {
logFileNames = make(map[LogLevel]string)
loglevel = make(map[LogLevel]string)
logFileNames[0] = ".log"
loglevel[LvDEBUG] = "DEBUG"
loglevel[LvINFO] = "INFO"
loglevel[LvWARN] = "WARN"
loglevel[LvERROR] = "ERROR"
}
const (
LogFile = iota
LogConsole
LogFileAndConsole
)
type logger struct {
loggers map[LogLevel]*log.Logger
files map[LogLevel]*os.File
level LogLevel
logDir string
mtx *sync.Mutex
lineEnding string
pid int
maxLogSize int64
mode int
}
func NewLogger(path string, filePrefix string, level LogLevel, maxLogSize int64, mode int) *logger {
loggers := make(map[LogLevel]*log.Logger)
logfiles := make(map[LogLevel]*os.File)
var (
logdir string
)
if path == "" {
logdir = "log/"
} else {
logdir = path + "/log/"
}
os.MkdirAll(logdir, 0777)
for lv := range logFileNames {
logFilePath := logdir + filePrefix + logFileNames[lv]
f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatal(err)
}
os.Chmod(logFilePath, 0666)
logfiles[lv] = f
loggers[lv] = log.New(f, "", log.LstdFlags)
}
var le string
if runtime.GOOS == "windows" {
le = "\r\n"
} else {
le = "\n"
}
pLog := &logger{loggers, logfiles, level, logdir, &sync.Mutex{}, le, os.Getpid(), maxLogSize, mode}
go pLog.checkFile()
return pLog
}
func (l *logger) setLevel(level LogLevel) {
l.mtx.Lock()
defer l.mtx.Unlock()
l.level = level
}
func (l *logger) setMode(mode int) {
l.mtx.Lock()
defer l.mtx.Unlock()
l.mode = mode
}
func (l *logger) checkFile() {
if l.maxLogSize <= 0 {
return
}
ticker := time.NewTicker(time.Minute)
for {
select {
case <-ticker.C:
l.mtx.Lock()
for lv, logFile := range l.files {
f, e := logFile.Stat()
if e != nil {
continue
}
if f.Size() <= l.maxLogSize {
continue
}
logFile.Close()
fname := f.Name()
backupPath := l.logDir + fname + ".0"
os.Remove(backupPath)
os.Rename(l.logDir+fname, backupPath)
newFile, e := os.OpenFile(l.logDir+fname, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if e == nil {
l.loggers[lv].SetOutput(newFile)
l.files[lv] = newFile
}
}
l.mtx.Unlock()
}
}
}
func (l *logger) Printf(level LogLevel, format string, params ...interface{}) {
l.mtx.Lock()
defer l.mtx.Unlock()
if level < l.level {
return
}
pidAndLevel := []interface{}{l.pid, loglevel[level]}
params = append(pidAndLevel, params...)
if l.mode == LogFile || l.mode == LogFileAndConsole {
l.loggers[0].Printf("%d %s "+format+l.lineEnding, params...)
}
if l.mode == LogConsole || l.mode == LogFileAndConsole {
log.Printf("%d %s "+format+l.lineEnding, params...)
}
}
func (l *logger) Println(level LogLevel, params ...interface{}) {
l.mtx.Lock()
defer l.mtx.Unlock()
if level < l.level {
return
}
pidAndLevel := []interface{}{l.pid, " ", loglevel[level], " "}
params = append(pidAndLevel, params...)
params = append(params, l.lineEnding)
if l.mode == LogFile || l.mode == LogFileAndConsole {
l.loggers[0].Print(params...)
}
if l.mode == LogConsole || l.mode == LogFileAndConsole {
log.Print(params...)
}
}