add new code
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// +build !windows
|
||||
|
||||
package tlog
|
||||
|
||||
import (
|
||||
|
||||
216
tlog/logger_windows.go
Normal file
216
tlog/logger_windows.go
Normal file
@@ -0,0 +1,216 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package tlog
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var l *Logger
|
||||
var mu sync.Mutex
|
||||
|
||||
type Logger struct {
|
||||
fileSize int64
|
||||
fileNum int
|
||||
fileName string
|
||||
host string
|
||||
debug bool
|
||||
tag string
|
||||
level LEVEL
|
||||
dir string
|
||||
ch chan *Atom
|
||||
f *os.File
|
||||
w *bufio.Writer
|
||||
bytePool *sync.Pool
|
||||
}
|
||||
|
||||
type Atom struct {
|
||||
line int
|
||||
file string
|
||||
format string
|
||||
level LEVEL
|
||||
args []interface{}
|
||||
data map[string]interface{}
|
||||
}
|
||||
|
||||
func newLogger(config Config) *Logger {
|
||||
logger := &Logger{
|
||||
dir: config.Dir,
|
||||
fileSize: int64(config.FileSize * 1024 * 1024),
|
||||
fileNum: config.FileNum,
|
||||
fileName: filepath.Join(config.Dir, config.FileName+".log"),
|
||||
tag: config.Tag,
|
||||
debug: config.Debug,
|
||||
level: getLevel(config.Level),
|
||||
ch: make(chan *Atom, 102400),
|
||||
bytePool: &sync.Pool{New: func() interface{} { return new(bytes.Buffer) }},
|
||||
}
|
||||
|
||||
host, _ := os.Hostname()
|
||||
ss := strings.Split(host, "-")
|
||||
if len(ss) < 2 {
|
||||
logger.host = host
|
||||
} else {
|
||||
logger.host = ss[len(ss)-2] + ss[len(ss)-1]
|
||||
}
|
||||
|
||||
if logger.debug {
|
||||
return logger
|
||||
}
|
||||
|
||||
os.MkdirAll(logger.dir, 0755)
|
||||
logger.f, _ = os.OpenFile(logger.fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
logger.w = bufio.NewWriterSize(logger.f, 1024*1024)
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
func (l *Logger) run() {
|
||||
if l.debug {
|
||||
return
|
||||
}
|
||||
go l.flush()
|
||||
go l.start()
|
||||
}
|
||||
|
||||
func (l *Logger) start() {
|
||||
for {
|
||||
a := <-l.ch
|
||||
if a == nil {
|
||||
l.flushNow()
|
||||
continue
|
||||
}
|
||||
b := l.bytes(a)
|
||||
l.w.Write(b)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) flushNow() {
|
||||
l.w.Flush()
|
||||
info, err := os.Stat(l.fileName)
|
||||
if err == nil && info.Size() > l.fileSize {
|
||||
l.rotate()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) rotate() {
|
||||
l.f.Close()
|
||||
newName := l.logname()
|
||||
os.Rename(l.fileName, newName)
|
||||
l.f, _ = os.OpenFile(l.fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
l.w.Reset(l.f)
|
||||
|
||||
// 简化版本,不做保留 N 个旧日志处理
|
||||
}
|
||||
|
||||
func (l *Logger) flush() {
|
||||
for range time.NewTicker(time.Second).C {
|
||||
l.ch <- nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) stop() {
|
||||
if l != nil && l.w != nil {
|
||||
l.w.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) getTag() string {
|
||||
if l != nil {
|
||||
return l.tag
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (l *Logger) bytes(a *Atom) []byte {
|
||||
w := l.bytePool.Get().(*bytes.Buffer)
|
||||
defer func() {
|
||||
w.Reset()
|
||||
l.bytePool.Put(w)
|
||||
}()
|
||||
|
||||
w.Write(l.genTime())
|
||||
fmt.Fprintf(w, "%s %s %s %s:%d ", l.host, l.tag, levelText[a.level], a.file, a.line)
|
||||
if a.format == "" {
|
||||
for _, arg := range a.args {
|
||||
w.WriteByte(' ')
|
||||
fmt.Fprint(w, arg)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(w, a.format, a.args...)
|
||||
}
|
||||
w.WriteByte('\n')
|
||||
b := make([]byte, w.Len())
|
||||
copy(b, w.Bytes())
|
||||
return b
|
||||
}
|
||||
|
||||
func (l *Logger) logname() string {
|
||||
now := time.Now().Format("20060102_150405")
|
||||
return fmt.Sprintf("%s.%s", l.fileName, now)
|
||||
}
|
||||
|
||||
func (l *Logger) getFileNameAndLine() (string, int) {
|
||||
_, file, line, ok := runtime.Caller(3)
|
||||
if !ok {
|
||||
return "???", 1
|
||||
}
|
||||
dirs := strings.Split(file, string(os.PathSeparator))
|
||||
if len(dirs) >= 2 {
|
||||
return dirs[len(dirs)-2] + "/" + dirs[len(dirs)-1], line
|
||||
}
|
||||
return file, line
|
||||
}
|
||||
|
||||
func (l *Logger) p(level LEVEL, args ...interface{}) {
|
||||
file, line := l.getFileNameAndLine()
|
||||
if l == nil || l.debug {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
fmt.Printf("%s%s %s %s:%d ", l.genTime(), l.getTag(), levelText[level], file, line)
|
||||
fmt.Println(args...)
|
||||
return
|
||||
}
|
||||
if level >= l.level {
|
||||
select {
|
||||
case l.ch <- &Atom{file: file, line: line, level: level, args: args}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) pf(level LEVEL, format string, args ...interface{}) {
|
||||
file, line := l.getFileNameAndLine()
|
||||
if l == nil || l.debug {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
fmt.Printf("%s%s %s %s:%d ", l.genTime(), l.getTag(), levelText[level], file, line)
|
||||
fmt.Printf(format, args...)
|
||||
fmt.Println()
|
||||
return
|
||||
}
|
||||
if level >= l.level {
|
||||
select {
|
||||
case l.ch <- &Atom{file: file, line: line, format: format, level: level, args: args}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) genTime() []byte {
|
||||
now := time.Now()
|
||||
return []byte(now.Format("01-02 15:04:05 "))
|
||||
}
|
||||
|
||||
func (l *Logger) pj(level LEVEL, m map[string]interface{}) {
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user