zoukankan      html  css  js  c++  java
  • log4go的全局封装Wrapper和标准log库函数的兼容

    方便易用的全局函数

    大多数时候,只不过是写一个简单的测试程序。例如:

    package main
    
    import (
        "log"
    )
    
    func main(){
        log.Fatal("Come with fatal,exit with 1 
    ")
    }
    

    这是Go语言标准log库的用法。

    无须用logger := log.New(...)来产生一个指针。而且可以在程序的任何地方都能使用这个log。

    阅读 log.go 源码:

    ...
    var std = New(os.Stderr, "", LstdFlags)
    ...
    // Fatal is equivalent to Print() followed by a call to os.Exit(1).
    func Fatal(v ...interface{}) {
    	std.Output(2, fmt.Sprint(v...))
    	os.Exit(1)
    }
    

    奥妙就在于 log.go 申请了一个全局变量 std,并封装了全局函数 log.Fatal。

    log4go 的一个简单例子

    这是 log4go 的一个简单例子:

    package main
    
    import (
    	"time"
    	log "github.com/ccpaging/log4go"
    	"github.com/ccpaging/log4go/colorlog"
    )
    
    func main() {
    	log.AddFilter("stdout", log.DEBUG, colorlog.NewColorLogWriter())
    	log.Debug("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02"))
    	log.Info("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02"))
    	log.Warn("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02"))
    
    	time.Sleep(200 * time.Millisecond)
    }
    

    效果如下图:

    colorlog

    是不是很漂亮?运行环境:windows ConEmu。
    colorlog 目前可以支持 Windows、Linux 以及 Cygwin 的 mintty 和 tmux

    tmux

    github.com/ccpaging/log4go/colorlog,这是一个彩色字符终端的log4go扩展插件。

    喧宾夺主了……color term log 的话题以后再聊。

    全局变量和全局函数

    所以,log4go也有一个全局变量和一堆全局函数封装。详见:wrapper.go

    var (
    	Global Logger
    )
    
    func init() {
    	Global = Logger {
    		"stdout": NewFilter(DEBUG, NewConsoleLogWriter().SetFormat("%T %L %s %M")),
    	}
    }
    
    // Wrapper for (*Logger).AddFilter
    func AddFilter(name string, lvl Level, writer LogWriter) {
    	Global.AddFilter(name, lvl, writer)
    }
    

    全局变量Global被自动初始化为一个 ConsoleLogWriter。它是黑白两色的字符终端。

    // Add a new LogWriter to the Logger which will only log messages at lvl or
    // higher.  This function should not be called from multiple goroutines.
    // Returns the logger for chaining.
    func (log Logger) AddFilter(name string, lvl Level, writer LogWriter) Logger {
    	if filt, isExist := log[name]; isExist {
    		filt.Close()
    		delete(log, name)
    	}
    	log[name] = NewFilter(lvl, writer)
    	return log
    }
    
    

    加入 ColorLogWriter 时,使用了同样的关键字 stdout
    所以,原来的黑白终端输出被关闭,Global 中只保留了新的彩色终端。

    如果 AddFilter 时,换一个关键字,例如 xxxout 会怎样?我不知道。
    系统不会崩溃吧 :(

    兼容标准log库

    为了方便习惯于标准log库的程序员,封装了与标准库兼容的函数。
    原来使用标准 log 库的程序只需换成 log4go 就可以用了?
    想得美?!这是一个值得尝试的设想……

        func Fatal(v ...interface{})
        func Fatalf(format string, v ...interface{})
        func Fatalln(v ...interface{})
        func Output(calldepth int, s string) error
        func Panic(v ...interface{})
        func Panicf(format string, v ...interface{})
        func Panicln(v ...interface{})
        func Print(v ...interface{})
        func Printf(format string, v ...interface{})
        func Println(v ...interface{})
    

    后续可能会加入:

        func Prefix() string
        func SetPrefix(prefix string)
    

    这个功能也许在nanomsg的订阅模型中用到。

    异步写日志的坑

    细心的童鞋可能注意到测试程序中的一个特殊语句。

    time.Sleep(200 * time.Millisecond)
    

    纳尼?延时了200ms。我承认,这个问题令人困惑。如果没有这个延时,
    可能在终端上什么也看不到。后果很严重……考试通不过,挂科……惨……

    log4go 的每个日志都在一个 go routine 中运行。如果测试程序写的太简单了,
    go routine 还没有来得及运行,主程序就退出了。

    曾经设想在go routine中加 channel……然并没有什么用……

    睡 200ms 是最优雅的解决方案了。

    就酱紫。

  • 相关阅读:
    vue2.X对接高德地图:vue-amap(一)
    RequestHeaders添加自定义参数
    git 拉取远程分支到本地
    git输错密码怎么办?
    webstorm最新版破解
    flex布局
    call和apply区别
    localStorage,sessionStorage,cookie
    详解单页面路由的几种实现原理(附demo)
    微信的踩坑之路----微信分享title和icon不显示
  • 原文地址:https://www.cnblogs.com/ccpaging/p/7218626.html
Copyright © 2011-2022 走看看