1 Star 0 Fork 0

api-go / revel-cmd

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
handlers.go 9.22 KB
一键复制 编辑 原始数据 按行查看 历史
package logger
import (
"io"
"os"
colorable "github.com/mattn/go-colorable"
"github.com/revel/log15"
"gopkg.in/natefinch/lumberjack.v2"
)
// Filters out records which do not match the level
// Uses the `log15.FilterHandler` to perform this task
func LevelHandler(lvl LogLevel, h LogHandler) LogHandler {
l15Lvl := log15.Lvl(lvl)
return log15.FilterHandler(func(r *log15.Record) (pass bool) {
return r.Lvl == l15Lvl
}, h)
}
// Filters out records which do not match the level
// Uses the `log15.FilterHandler` to perform this task
func MinLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
l15Lvl := log15.Lvl(lvl)
return log15.FilterHandler(func(r *log15.Record) (pass bool) {
return r.Lvl <= l15Lvl
}, h)
}
// Filters out records which match the level
// Uses the `log15.FilterHandler` to perform this task
func NotLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
l15Lvl := log15.Lvl(lvl)
return log15.FilterHandler(func(r *log15.Record) (pass bool) {
return r.Lvl != l15Lvl
}, h)
}
// Adds in a context called `caller` to the record (contains file name and line number like `foo.go:12`)
// Uses the `log15.CallerFileHandler` to perform this task
func CallerFileHandler(h LogHandler) LogHandler {
return log15.CallerFileHandler(h)
}
// Adds in a context called `caller` to the record (contains file name and line number like `foo.go:12`)
// Uses the `log15.CallerFuncHandler` to perform this task
func CallerFuncHandler(h LogHandler) LogHandler {
return log15.CallerFuncHandler(h)
}
// Filters out records which match the key value pair
// Uses the `log15.MatchFilterHandler` to perform this task
func MatchHandler(key string, value interface{}, h LogHandler) LogHandler {
return log15.MatchFilterHandler(key, value, h)
}
// If match then A handler is called otherwise B handler is called
func MatchAbHandler(key string, value interface{}, a, b LogHandler) LogHandler {
return log15.FuncHandler(func(r *log15.Record) error {
for i := 0; i < len(r.Ctx); i += 2 {
if r.Ctx[i] == key {
if r.Ctx[i+1] == value {
if a != nil {
return a.Log(r)
}
return nil
}
}
}
if b != nil {
return b.Log(r)
}
return nil
})
}
// The nil handler is used if logging for a specific request needs to be turned off
func NilHandler() LogHandler {
return log15.FuncHandler(func(r *log15.Record) error {
return nil
})
}
// Match all values in map to log
func MatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
return matchMapHandler(matchMap, false, a)
}
// Match !(Match all values in map to log) The inverse of MatchMapHandler
func NotMatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
return matchMapHandler(matchMap, true, a)
}
// Rather then chaining multiple filter handlers, process all here
func matchMapHandler(matchMap map[string]interface{}, inverse bool, a LogHandler) LogHandler {
return log15.FuncHandler(func(r *log15.Record) error {
checkMap := map[string]bool{}
// Copy the map to a bool
for i := 0; i < len(r.Ctx); i += 2 {
if value, found := matchMap[r.Ctx[i].(string)]; found && value == r.Ctx[i+1] {
checkMap[r.Ctx[i].(string)] = true
}
}
if len(checkMap) == len(matchMap) {
if !inverse {
return a.Log(r)
}
} else if inverse {
return a.Log(r)
}
return nil
})
}
// Filters out records which do not match the key value pair
// Uses the `log15.FilterHandler` to perform this task
func NotMatchHandler(key string, value interface{}, h LogHandler) LogHandler {
return log15.FilterHandler(func(r *log15.Record) (pass bool) {
switch key {
case r.KeyNames.Lvl:
return r.Lvl != value
case r.KeyNames.Time:
return r.Time != value
case r.KeyNames.Msg:
return r.Msg != value
}
for i := 0; i < len(r.Ctx); i += 2 {
if r.Ctx[i] == key {
return r.Ctx[i+1] == value
}
}
return true
}, h)
}
func MultiHandler(hs ...LogHandler) LogHandler {
// Convert the log handlers to log15.Handlers
handlers := []log15.Handler{}
for _, h := range hs {
if h != nil {
handlers = append(handlers, h)
}
}
return log15.MultiHandler(handlers...)
}
// Outputs the records to the passed in stream
// Uses the `log15.StreamHandler` to perform this task
func StreamHandler(wr io.Writer, fmtr LogFormat) LogHandler {
return log15.StreamHandler(wr, fmtr)
}
// Filter handler, this is the only
// Uses the `log15.FilterHandler` to perform this task
func FilterHandler(fn func(r *log15.Record) bool, h LogHandler) LogHandler {
return log15.FilterHandler(fn, h)
}
type ListLogHandler struct {
handlers []LogHandler
}
func NewListLogHandler(h1, h2 LogHandler) *ListLogHandler {
ll := &ListLogHandler{handlers: []LogHandler{h1, h2}}
return ll
}
func (ll *ListLogHandler) Log(r *log15.Record) (err error) {
for _, handler := range ll.handlers {
if err == nil {
err = handler.Log(r)
} else {
handler.Log(r)
}
}
return
}
func (ll *ListLogHandler) Add(h LogHandler) {
if h != nil {
ll.handlers = append(ll.handlers, h)
}
}
func (ll *ListLogHandler) Del(h LogHandler) {
if h != nil {
for i, handler := range ll.handlers {
if handler == h {
ll.handlers = append(ll.handlers[:i], ll.handlers[i+1:]...)
}
}
}
}
type CompositeMultiHandler struct {
DebugHandler LogHandler
InfoHandler LogHandler
WarnHandler LogHandler
ErrorHandler LogHandler
CriticalHandler LogHandler
}
func NewCompositeMultiHandler() (*CompositeMultiHandler, LogHandler) {
cw := &CompositeMultiHandler{}
return cw, cw
}
func (h *CompositeMultiHandler) Log(r *log15.Record) (err error) {
var handler LogHandler
switch r.Lvl {
case log15.LvlInfo:
handler = h.InfoHandler
case log15.LvlDebug:
handler = h.DebugHandler
case log15.LvlWarn:
handler = h.WarnHandler
case log15.LvlError:
handler = h.ErrorHandler
case log15.LvlCrit:
handler = h.CriticalHandler
}
// Embed the caller function in the context
if handler != nil {
handler.Log(r)
}
return
}
func (h *CompositeMultiHandler) SetHandler(handler LogHandler, replace bool, level LogLevel) {
if handler == nil {
// Ignore empty handler
return
}
source := &h.DebugHandler
switch level {
case LvlDebug:
source = &h.DebugHandler
case LvlInfo:
source = &h.InfoHandler
case LvlWarn:
source = &h.WarnHandler
case LvlError:
source = &h.ErrorHandler
case LvlCrit:
source = &h.CriticalHandler
}
if !replace && *source != nil {
// If this already was a list add a new logger to it
if ll, found := (*source).(*ListLogHandler); found {
ll.Add(handler)
} else {
*source = NewListLogHandler(*source, handler)
}
} else {
*source = handler
}
}
func (h *CompositeMultiHandler) SetHandlers(handler LogHandler, options *LogOptions) {
if len(options.Levels) == 0 {
options.Levels = LvlAllList
}
// Set all levels
for _, lvl := range options.Levels {
h.SetHandler(handler, options.ReplaceExistingHandler, lvl)
}
}
func (h *CompositeMultiHandler) SetJson(writer io.Writer, options *LogOptions) {
handler := CallerFileHandler(StreamHandler(writer, log15.JsonFormatEx(
options.GetBoolDefault("pretty", false),
options.GetBoolDefault("lineSeparated", true),
)))
if options.HandlerWrap != nil {
handler = options.HandlerWrap.SetChild(handler)
}
h.SetHandlers(handler, options)
}
// Use built in rolling function
func (h *CompositeMultiHandler) SetJsonFile(filePath string, options *LogOptions) {
writer := &lumberjack.Logger{
Filename: filePath,
MaxSize: options.GetIntDefault("maxSizeMB", 1024), // megabytes
MaxAge: options.GetIntDefault("maxAgeDays", 7), //days
MaxBackups: options.GetIntDefault("maxBackups", 7),
Compress: options.GetBoolDefault("compress", true),
}
h.SetJson(writer, options)
}
func (h *CompositeMultiHandler) SetTerminal(writer io.Writer, options *LogOptions) {
streamHandler := StreamHandler(
writer,
TerminalFormatHandler(
options.GetBoolDefault("noColor", false),
options.GetBoolDefault("smallDate", true)))
if os.Stdout == writer {
streamHandler = StreamHandler(
colorable.NewColorableStdout(),
TerminalFormatHandler(
options.GetBoolDefault("noColor", false),
options.GetBoolDefault("smallDate", true)))
} else if os.Stderr == writer {
streamHandler = StreamHandler(
colorable.NewColorableStderr(),
TerminalFormatHandler(
options.GetBoolDefault("noColor", false),
options.GetBoolDefault("smallDate", true)))
}
handler := CallerFileHandler(streamHandler)
if options.HandlerWrap != nil {
handler = options.HandlerWrap.SetChild(handler)
}
h.SetHandlers(handler, options)
}
// Use built in rolling function
func (h *CompositeMultiHandler) SetTerminalFile(filePath string, options *LogOptions) {
writer := &lumberjack.Logger{
Filename: filePath,
MaxSize: options.GetIntDefault("maxSizeMB", 1024), // megabytes
MaxAge: options.GetIntDefault("maxAgeDays", 7), //days
MaxBackups: options.GetIntDefault("maxBackups", 7),
Compress: options.GetBoolDefault("compress", true),
}
h.SetTerminal(writer, options)
}
func (h *CompositeMultiHandler) Disable(levels ...LogLevel) {
if len(levels) == 0 {
levels = LvlAllList
}
for _, level := range levels {
switch level {
case LvlDebug:
h.DebugHandler = nil
case LvlInfo:
h.InfoHandler = nil
case LvlWarn:
h.WarnHandler = nil
case LvlError:
h.ErrorHandler = nil
case LvlCrit:
h.CriticalHandler = nil
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/netscript/revel-cmd.git
git@gitee.com:netscript/revel-cmd.git
netscript
revel-cmd
revel-cmd
v0.20.0

搜索帮助

344bd9b3 5694891 D2dac590 5694891