当前位置: 首页 > 工具软件 > nxlog4go > 使用案例 >

go语言中日志第三方包log4go的使用

和柏
2023-12-01

文中通过加载配置文件使用log4go。

一、下载log4go

二、配置文件log4go.xml

<!--
  ~ Copyright (c) 2017 - 3. by ZanderWong. All rights reserved.
  ~ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  -->

<logging>
    <filter enabled="true">
        <tag>stdout</tag>
        <type>console</type>
        <!-- level is (:?FINEST|FINE|DEBUG|TRACE|INFO|WARNING|ERROR) -->
        <level>INFO</level>
    </filter>
    <filter enabled="true">
        <tag>file</tag>
        <type>file</type>
        <level>DEBUG</level>
        <property name="filename">test_client.log</property>
        <!--
           %T - Time (15:04:05 MST)
           %t - Time (15:04)
           %D - Date (2006/01/02)
           %d - Date (01/02/06)
           %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT)
           %S - Source
           %M - Message
           It ignores unknown format strings (and removes them)
           Recommended: "[%D %T] [%L] (%S) %M"
        -->
        <property name="format">[%D %T] [%L] (%S) %M</property>
        <property name="rotate">true</property> <!-- true enables log rotation, otherwise append -->
        <property name="maxsize">10M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
        <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands -->
        <property name="daily">false
        </property> <!-- Automatically rotates when a log message is written after midnight -->
    </filter>
    <filter enabled="false">
        <tag>xmllog</tag>
        <type>xml</type>
        <level>TRACE</level>
        <property name="filename">trace.xml</property>
        <property name="rotate">true</property> <!-- true enables log rotation, otherwise append -->
        <property name="maxsize">100M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
        <property name="maxrecords">6K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands -->
        <property name="daily">false
        </property> <!-- Automatically rotates when a log message is written after midnight -->
    </filter>
    <filter enabled="false"><!-- enabled=false means this logger won't actually be created -->
        <tag>donotopen</tag>
        <type>socket</type>
        <level>FINEST</level>
        <property name="endpoint">192.168.1.255:12124</property> <!-- recommend UDP broadcast -->
        <property name="protocol">udp</property> <!-- tcp or udp -->
    </filter>
</logging>

三、使用

log4go.LoadConfiguration("log4go.xml")

这样将会在go项目的当前文件夹里生成一个test_client.log的日志文件。项目中通过log4go.Info(""),log4go.Error("")等写入日志

四、拓展

参考第二步配置文件的红色部分,若改为

<property name="filename">log/test_client.log</property>
再运行就会报错
FileLogWriter("log/test_client.log"): open log/test_client.log: The system cannot find the path specified.
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference

因为找不到目录log。为此对log4go的filelog.go的NewFileLogWriter(fname string,rotate bool)方法进行了修改。

func NewFileLogWriter(fname string, rotate bool) *FileLogWriter {
	var end, endL, endR int
	endL = strings.LastIndex(fname, "/")
	endR = strings.LastIndex(fname, "\\")
	if endL > endR {
		end = endL
	} else {
		end = endR
	}
	if end != -1 {
		folder := fname[0:end]
		res, err := PathExists(folder)
		if err != nil {
			fmt.Println("err:", err)
		}
		if !res {
			err := os.MkdirAll(folder, 0777)
			if err != nil {
				fmt.Println("err:", err)
			} else {
				fmt.Println("create directory success!")
			}
		}
	}
	w := &FileLogWriter{
		rec:       make(chan *LogRecord, LogBufferLength),
		rot:       make(chan bool),
		filename:  fname,
		format:    "[%D %T] [%L] (%S) %M",
		rotate:    rotate,
		maxbackup: 999,
	}
	// open the file for the first time
	if err := w.intRotate(); err != nil {
		fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
		return nil
	}
	go func() {
		defer func() {
			if w.file != nil {
				fmt.Fprint(w.file, FormatLogRecord(w.trailer, &LogRecord{Created: time.Now()}))
				w.file.Close()
			}
		}()
		for {
			select {
			case <-w.rot:
				if err := w.intRotate(); err != nil {
					fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
					return
				}
			case rec, ok := <-w.rec:
				if !ok {
					return
				}
				now := time.Now()
				if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) ||
					(w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) ||
					(w.daily && now.Day() != w.daily_opendate) {
					if err := w.intRotate(); err != nil {
						fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
						return
					}
				}
				// Perform the write
				n, err := fmt.Fprint(w.file, FormatLogRecord(w.format, rec))
				if err != nil {
					fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
					return
				}
				// Update the counts
				w.maxlines_curlines++
				w.maxsize_cursize += n
			}
		}
	}()
	return w
}
//determine if a file or folder exists
//if bool is true,the file or folder exists
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}
再次运行,就会在 go项目的当前文件夹里生成log/ test_client.log。
 类似资料: