• nxlog4go 的配置驱动


    刚开始接触log4go项目时,没有注意到配置的重要性。

    阅读了log4j、log4net、log4cpp、log4cplus的部分代码,发现它们都是以xml配置来驱动日志系统运行的。


    多个源文件共享一个logger

    最简单的方式是新建一个logger.go文件。

    package main
    
    import (
    	l4g "github.com/ccpaging/nxlog4go"
    	"github.com/ccpaging/nxlog4go/color"
    	"github.com/ccpaging/nxlog4go/file"
    	"github.com/ccpaging/nxlog4go/socket"
    )
    
    var log = l4g.GetLogger()
    

    l4g.GetLogger() 从nxlog4go中取出预定义的logger。

    或者用l4g.New(l4g.DEBUG) 新建全局 Logger。

    var log = l4g.New(l4g.DEBUG)
    

    初始化logger

    可以在新建时直接链接配置函数。

    var log = l4g.GetLogger().SetCaller(false).SetPattern("[%T] [%L] (%s) %M
    ")
    

    或者在init()中配置,如果不使用配置文件的话。

    var log = l4g.GetLogger()
    
    init() {
        log = log.SetCaller(false).SetPattern("[%T] [%L] (%s) %M
    ")
    }
    

    准备 xml 配置文件

    准备xml配置文件。详见:config.xml

    方便的办法是参照以上文件进行修改。

    以 color term appender 为例

    <logging>
    	<filter enabled="true">
    	    <tag>color</tag>
    	    <level>DEBUG</level>
    		<property name="pattern">[%D %T] [%L] (%s) %M%R</property>
    	</filter>
    </logging>
    
    • enabled - filter attribute

      Filter或称为 Appender的使能属性。enabled = true,打开。enabled = false,关闭。

    • tag

      在log4go里用了两个字段——tag和type。在 nxlog4go 中合并成一个,标识 Appender 的类型。

      在程序中,nxlog4go预装载(Preload)所有可能用到的 Appender,指定每个 Appender 的 tag。

      然后装载配置文件,用 tag 字段匹配 Appender。

      通过 Preload - tag - Load 机制,nxlog4go 可以用配置驱动未知的扩展 Appender。

    • level

      日志过滤级别。nxlog4go仅处理大于等于 level 的日志。

    • property - attribute

      每种 Appender 都有自己的 Options。

      例如上例中设置 PatternLayout 的Pattern。“%R”表示回车换行,即程序中的“ ”。

      通过参看源文件可以获得详细的信息。例如:filelog.go

    func (fa *FileAppender) SetOption(name string, v interface{}) error {
    	fa.mu.Lock()
    	defer fa.mu.Unlock()
    
    	switch name {
    	case "filename":
    		...
    	case "flush":
    		...
    	case "maxbackup":
    		...
    	case "cycle":
    		...
    	case "clock", "delay0":
    		...
    	case "daily":
    		...
    	case "maxsize":
    		...
    	case "pattern", "format", "utc":
    		...
    	case "head":
    		...
    	case "foot":
    		...
    	default:
    		return l4g.ErrBadOption
    	}
    	return nil
    }
    

    装载 xml 配置驱动nxlog4go运行

    func main() {
    	// 打开xml配置文件
    	fd, err := os.Open(filename)
    	if err != nil {
    		panic(fmt.Sprintf("Can't load xml config file: %s %v", filename, err))
    	}
    	// 读取xml内容到buf
    	buf, err := ioutil.ReadAll(fd)
    	if err != nil {
    		fmt.Fprintf(os.Stderr, "Could not read %q: %s
    ", filename, err)
    		os.Exit(1)
    	}
    	// 关闭配置文件
    	fd.Close()
    
    	// 新建logger config, 具体结构详见filters.go, appender.go
    	xc := new(l4g.LoggerConfig)
    	if err := xml.Unmarshal(buf, xc); err != nil {
    		fmt.Fprintf(os.Stderr, "Could not parse XML configuration. %s
    ", err)
    		os.Exit(1)
    	}
    
    	// 新建filters
    	fs := l4g.NewFilters()
    
    	// 预装载所有可能用到的 Appender
    	fs.Preload("color", colorlog.NewAppender())
    	fs.Preload("file", filelog.NewAppender("_test.log", 0))
    	fs.Preload("socket", socketlog.NewAppender("udp", "127.0.0.1:12124"))
    
    	// 预装载 xml 格式日志文件
    	xa := filelog.NewAppender("_test.log", 0)
    	xa.SetOption("head","<log created="%D %T">%R")
    
    	xa.SetOption("pattern", 
    `	<record level="%L">
    		<timestamp>%D %T</timestamp>
    		<source>%S</source>
    		<message>%M</message>
    	</record>%R`)
    
    	xa.SetOption("foot", "</log>%R")
    	fs.Preload("xml", xa)
    	
    	fmt.Println(len(*fs), "appenders pre-installed")
    
    	// 装载配置并自动删除未用的appender
    	fs.LoadConfiguration(xc.Filters)
    	if filt, isExist := (*fs)["color"]; isExist {
    		// 已有 color term appender. 关闭缺省的 writer
    		log.SetOutput(nil)
    	}
    	log.SetFilters(fs)
    	fmt.Println(len(*fs), "appenders configured ok")
    
    	// And now we're ready!
    	log.Finest("This will only go to those of you really cool UDP kids!  If you change enabled=true.")
    	log.Debug("Oh no!  %d + %d = %d!", 2, 2, 2+2)
    	log.Trace("Oh no!  %d + %d = %d!", 2, 2, 2+2)
    	log.Info("About that time, eh chaps?")
    
    	log.Shutdown()
    
    	// 或者分步执行
    
    	// 卸载filters
    	// log.SetFilters(nil)
    	// 关闭全部filters
    	// fs.Close()
    }
    

    xml 格式的日志文件

    附带实现了xml格式的日志文件。简单的设置 Head, Foot, 和PatternLayout就可以。例如:

    	xa := filelog.NewAppender("_test.log", 0)
    	xa.SetOption("head","<log created="%D %T">%R")
    
    	xa.SetOption("pattern", 
    `	<record level="%L">
    		<timestamp>%D %T</timestamp>
    		<source>%S</source>
    		<message>%M</message>
    	</record>%R`)
    
    	xa.SetOption("foot", "</log>%R")
    

    生成的日志文件内容如下:

    <log created="2018/03/26 13:50:25">
        <record level="TRAC">
            <timestamp>2018/03/26 13:50:25</timestamp>
            <source>f:/go/src/github.com/ccpaging/nxlog4go/examples/xmlconfig.go</source>
            <message>Oh no!  2 + 2 = 4!</message>
        </record>
        <record level="INFO">
            <timestamp>2018/03/26 13:50:25</timestamp>
            <source>f:/go/src/github.com/ccpaging/nxlog4go/examples/xmlconfig.go</source>
            <message>About that time, eh chaps?</message>
        </record>
    
    • 只有滚动日志文件时才会写入 Foot

    参考源文件

    jsonconfig.go

    xmlconfig.go

  • 相关阅读:
    CF1454F Array Partition
    leetcode1883 准时抵达会议现场的最小跳过休息次数
    leetcode1871 跳跃游戏 VII
    leetcode1872 石子游戏VIII
    CF1355C Count Triangles
    CF1245D Shichikuji and Power Grid
    CF1368C Even Picture
    CF1368D AND, OR and square sum
    CF1395C Boboniu and Bit Operations
    SpringBoot和开发热部署
  • 原文地址:https://www.cnblogs.com/ccpaging/p/8650706.html
Copyright © 2020-2023  润新知