1 Star 0 Fork 0

jezzis / gohelpers

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
handler.go 4.19 KB
一键复制 编辑 原始数据 按行查看 历史
jezzis 提交于 2020-06-12 01:15 . fix: rotate logic
package mlog
import (
"errors"
"fmt"
"log"
"os"
"sync"
"time"
)
type Handler interface {
Log(r *Record)
Reload() error
Close()
}
type FileHandler struct {
filename string
filter []Filter
driver *log.Logger
fh *os.File
showLevel bool
flag int
}
func NewFileHandler(file string, fmt int) (h *FileHandler) {
h = &FileHandler{
filename: file,
}
if fmt == 0 {
h.flag = log.LstdFlags
} else {
h.flag = fmt
}
if err := h.init(); nil != err {
panic(err)
}
return
}
func NewBareHandler(file string) (h *FileHandler) {
h = NewFileHandler(file, 0)
return
}
func NewLevelHandler(file string, format int, level ...string) (h *FileHandler) {
h = NewFileHandler(file, format)
h.AddFilter(LevelFilter(level...))
h.showLevel = true
return
}
func (h *FileHandler) AddFilter(f ...Filter) {
h.filter = append(h.filter, f...)
}
func (h *FileHandler) setFormatFlag(fmt int) {
h.flag = fmt
h.driver.SetFlags(fmt)
}
func (h *FileHandler) Log(r *Record) {
for _, f := range h.filter {
if !f(r) {
return
}
}
var (
v = r.args
format = r.format
)
if h.showLevel {
v = append([]interface{}{r.level.String()}, v...)
if len(format) > 0 {
format = "%s " + r.format
}
}
if len(format) > 0 {
h.driver.Printf(format, v...)
} else {
h.driver.Println(v...)
}
}
func (h *FileHandler) Reload() (err error) {
if nil != h.fh {
if err = h.fh.Close(); nil != err {
h.fh = nil
}
}
return h.init()
}
func (h *FileHandler) Close() {
if nil != h.fh {
_ = h.fh.Close()
}
}
func (h *FileHandler) init() (err error) {
if len(h.filename) > 0 {
if h.fh, err = os.OpenFile(h.filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0664); nil != err {
log.Fatalf("logger: error open %s, %s", h.filename, err)
return
}
}
if nil != h.fh {
h.driver = log.New(h.fh, "", h.flag)
} else {
h.driver = log.New(os.Stdout, "", h.flag)
}
return
}
type RotateFileHandler struct {
FileHandler
file string
suffix string
rotateUnit uint8
}
func NewRotateFileHandler(file string, format int, rotateUnit uint8, level ...string) (h *RotateFileHandler) {
h = &RotateFileHandler{file: file, rotateUnit: rotateUnit}
h.suffix = h.getSuffix()
fh := NewLevelHandler(fmt.Sprintf("%s.%s", file, h.suffix), format, level...)
h.FileHandler = *fh
return
}
func (h *RotateFileHandler) getSuffix() string {
var (
now = time.Now()
suffix string
)
if h.rotateUnit == No {
return h.file
}
if h.rotateUnit == Secondly {
secSuffix := (now.Second() - now.Second()/3600*3600) % 5
//log.Printf("current sec: %d, suffix: %d", now.Second(), secSuffix)
suffix = fmt.Sprintf("%d-%02d-%02d-%02d%d", now.Year(), now.Month(), now.Day(), now.Hour(), secSuffix)
} else if h.rotateUnit == Hourly {
suffix = now.Format("2006-01-02-15")
} else if h.rotateUnit == Daily {
suffix = now.Format("2006-01-02")
} else if h.rotateUnit == Monthly {
suffix = now.Format("2006-01")
} else if h.rotateUnit == Yearly {
suffix = now.Format("2006")
} else {
panic(errors.New(fmt.Sprintf("unexpected rotate unit: %d", h.rotateUnit)))
}
return suffix
}
func (h *RotateFileHandler) Log(r *Record) {
suffix := h.getSuffix()
if h.rotateUnit > No && suffix != h.suffix {
h.suffix = suffix
h.filename = fmt.Sprintf("%s.%s", h.file, suffix)
//log.Printf("trigger reload")
_ = h.Reload()
}
h.FileHandler.Log(r)
}
type JsonHandler struct {
Handler
}
func NewJsonHandler(handler Handler) (h *JsonHandler) {
h = &JsonHandler{handler}
return
}
func (h *JsonHandler) Log(r *Record) {
h.Handler.Log(r.Json())
}
type SmartHandler struct {
Handler
ch chan *Record
wg *sync.WaitGroup
}
func NewSmartHandler(handler Handler) (h *SmartHandler) {
h = &SmartHandler{
Handler: handler,
ch: make(chan *Record),
wg: new(sync.WaitGroup),
}
h.wg.Add(1)
go h.consumer()
return
}
func (h *SmartHandler) consumer() {
defer h.wg.Done()
//defer h.Handler.Log(&Record{level: Debug, args: Args{"log consumer stoped"}})
//h.Handler.Log(&Record{level: Debug, args: Args{"log consumer started"}})
for r := range h.ch {
h.Handler.Log(r)
}
}
func (h *SmartHandler) Log(r *Record) {
h.ch <- r
}
func (h *SmartHandler) Close() {
defer h.Handler.Close()
close(h.ch)
h.wg.Wait()
}
Go
1
https://gitee.com/jezzis/go-helpers.git
git@gitee.com:jezzis/go-helpers.git
jezzis
go-helpers
gohelpers
9e9a7a50f73e

搜索帮助