zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    家庭记账本教程之增(java web基础版三)
    家庭记账本小程序之后台java代码部分(java web基础版二)
    家庭记账本小程序之前端页面设计(java web基础版一)
    面向对象
    装饰器详解
    Python开发【第六篇】:文件处理
    Python开发【第四篇】:运算符
    Python开发【第三篇】:分支循环
    Python开发【第五篇】:函数
    Atom 基本使用
  • 原文地址:https://www.cnblogs.com/ccpaging/p/8650706.html
Copyright © 2011-2022 走看看