install bug and new log api
This commit is contained in:
+107
-88
@@ -3,38 +3,33 @@ package openp2p
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LogLevel int
|
||||
type LogLevel int32
|
||||
|
||||
var gLog *logger
|
||||
|
||||
const (
|
||||
LvDev LogLevel = -1
|
||||
LvDEBUG LogLevel = iota
|
||||
LvINFO
|
||||
LvWARN
|
||||
LvERROR
|
||||
LvDEBUG LogLevel = 0
|
||||
LvINFO LogLevel = 1
|
||||
LvWARN LogLevel = 2
|
||||
LvERROR LogLevel = 3
|
||||
)
|
||||
|
||||
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"
|
||||
loglevel[LvDev] = "Dev"
|
||||
const logFileNames string = ".log"
|
||||
|
||||
var loglevel = map[LogLevel]string{
|
||||
LvDEBUG: "DEBUG",
|
||||
LvINFO: "INFO",
|
||||
LvWARN: "WARN",
|
||||
LvERROR: "ERROR",
|
||||
LvDev: "Dev",
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -43,62 +38,54 @@ const (
|
||||
)
|
||||
|
||||
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
|
||||
stdLogger *log.Logger
|
||||
logger *log.Logger
|
||||
files *os.File
|
||||
level atomic.Int32
|
||||
logDir string
|
||||
mtx sync.Mutex
|
||||
lineEnding string
|
||||
pid int
|
||||
maxLogSize atomic.Int64
|
||||
mode int
|
||||
stdLogger *log.Logger
|
||||
checkFileRunning bool
|
||||
}
|
||||
|
||||
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/"
|
||||
logdir := filepath.Join(path, "log")
|
||||
if err := os.MkdirAll(logdir, 0755); err != nil && mode&LogFile != 0 {
|
||||
return nil
|
||||
}
|
||||
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, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
os.Chmod(logFilePath, 0644)
|
||||
logfiles[lv] = f
|
||||
loggers[lv] = log.New(f, "", log.LstdFlags|log.Lmicroseconds)
|
||||
logFilePath := filepath.Join(logdir, filePrefix+logFileNames)
|
||||
f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil && mode&LogFile != 0 {
|
||||
log.Fatal(err)
|
||||
}
|
||||
var le string
|
||||
stdLog := log.New(f, "", log.LstdFlags|log.Lmicroseconds)
|
||||
le := "\n"
|
||||
if runtime.GOOS == "windows" {
|
||||
le = "\r\n"
|
||||
} else {
|
||||
le = "\n"
|
||||
}
|
||||
pLog := &logger{loggers, logfiles, level, logdir, &sync.Mutex{}, le, os.Getpid(), maxLogSize, mode, log.New(os.Stdout, "", 0)}
|
||||
pLog := &logger{logger: stdLog,
|
||||
files: f,
|
||||
logDir: logdir,
|
||||
lineEnding: le,
|
||||
pid: os.Getpid(),
|
||||
mode: mode,
|
||||
stdLogger: log.New(os.Stdout, "", 0)}
|
||||
pLog.setMaxSize(maxLogSize)
|
||||
pLog.setLevel(level)
|
||||
pLog.stdLogger.SetFlags(log.LstdFlags | log.Lmicroseconds)
|
||||
go pLog.checkFile()
|
||||
return pLog
|
||||
}
|
||||
|
||||
func (l *logger) setLevel(level LogLevel) {
|
||||
l.mtx.Lock()
|
||||
defer l.mtx.Unlock()
|
||||
l.level = level
|
||||
l.level.Store(int32(level))
|
||||
}
|
||||
|
||||
func (l *logger) setMaxSize(size int64) {
|
||||
l.mtx.Lock()
|
||||
defer l.mtx.Unlock()
|
||||
l.maxLogSize = size
|
||||
l.maxLogSize.Store(size)
|
||||
}
|
||||
|
||||
func (l *logger) setMode(mode int) {
|
||||
@@ -107,49 +94,61 @@ func (l *logger) setMode(mode int) {
|
||||
l.mode = mode
|
||||
}
|
||||
|
||||
func (l *logger) close() {
|
||||
l.checkFileRunning = false
|
||||
l.files.Close()
|
||||
}
|
||||
|
||||
func (l *logger) checkFile() {
|
||||
if l.maxLogSize <= 0 {
|
||||
if l.maxLogSize.Load() <= 0 {
|
||||
return
|
||||
}
|
||||
l.checkFileRunning = true
|
||||
ticker := time.NewTicker(time.Minute)
|
||||
for {
|
||||
for l.checkFileRunning {
|
||||
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, 0644)
|
||||
if e == nil {
|
||||
l.loggers[lv].SetOutput(newFile)
|
||||
l.files[lv] = newFile
|
||||
}
|
||||
f, e := l.files.Stat()
|
||||
if e != nil {
|
||||
continue
|
||||
}
|
||||
l.mtx.Unlock()
|
||||
if f.Size() <= l.maxLogSize.Load() {
|
||||
continue
|
||||
}
|
||||
l.mtx.Lock()
|
||||
l.files.Close()
|
||||
fname := f.Name()
|
||||
backupPath := filepath.Join(l.logDir, fname+".0")
|
||||
err := os.Remove(backupPath)
|
||||
if err != nil {
|
||||
log.Println("remove openp2p.log0 error:", err)
|
||||
}
|
||||
if err = os.Rename(filepath.Join(l.logDir, fname), backupPath); err != nil {
|
||||
log.Println("rename openp2p.log error:", err)
|
||||
}
|
||||
if newFile, e := os.OpenFile(filepath.Join(l.logDir, fname), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644); e == nil {
|
||||
|
||||
l.logger.SetOutput(newFile)
|
||||
l.files = newFile
|
||||
l.mtx.Unlock()
|
||||
}
|
||||
case <-time.After(time.Second * 1):
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (l *logger) Printf(level LogLevel, format string, params ...interface{}) {
|
||||
l.mtx.Lock()
|
||||
defer l.mtx.Unlock()
|
||||
if level < l.level {
|
||||
if level < LogLevel(l.level.Load()) {
|
||||
return
|
||||
}
|
||||
l.mtx.Lock()
|
||||
defer l.mtx.Unlock()
|
||||
|
||||
pidAndLevel := []interface{}{l.pid, loglevel[level]}
|
||||
params = append(pidAndLevel, params...)
|
||||
if l.mode&LogFile != 0 {
|
||||
l.loggers[0].Printf("%d %s "+format+l.lineEnding, params...)
|
||||
l.logger.Printf("%d %s "+format+l.lineEnding, params...)
|
||||
}
|
||||
if l.mode&LogConsole != 0 {
|
||||
l.stdLogger.Printf("%d %s "+format+l.lineEnding, params...)
|
||||
@@ -157,18 +156,38 @@ func (l *logger) Printf(level LogLevel, format string, params ...interface{}) {
|
||||
}
|
||||
|
||||
func (l *logger) Println(level LogLevel, params ...interface{}) {
|
||||
l.mtx.Lock()
|
||||
defer l.mtx.Unlock()
|
||||
if level < l.level {
|
||||
if level < LogLevel(l.level.Load()) {
|
||||
return
|
||||
}
|
||||
l.mtx.Lock()
|
||||
defer l.mtx.Unlock()
|
||||
pidAndLevel := []interface{}{l.pid, " ", loglevel[level], " "}
|
||||
params = append(pidAndLevel, params...)
|
||||
params = append(params, l.lineEnding)
|
||||
if l.mode&LogFile != 0 {
|
||||
l.loggers[0].Print(params...)
|
||||
l.logger.Print(params...)
|
||||
}
|
||||
if l.mode&LogConsole != 0 {
|
||||
l.stdLogger.Print(params...)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *logger) d(format string, params ...interface{}) {
|
||||
l.Printf(LvDEBUG, format, params...)
|
||||
}
|
||||
|
||||
func (l *logger) i(format string, params ...interface{}) {
|
||||
l.Printf(LvINFO, format, params...)
|
||||
}
|
||||
|
||||
func (l *logger) w(format string, params ...interface{}) {
|
||||
l.Printf(LvWARN, format, params...)
|
||||
}
|
||||
|
||||
func (l *logger) e(format string, params ...interface{}) {
|
||||
l.Printf(LvERROR, format, params...)
|
||||
}
|
||||
|
||||
func (l *logger) dev(format string, params ...interface{}) {
|
||||
l.Printf(LvDev, format, params...)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user