go log

first look at the example

package main

import (
	"log"
	"os"
)

func init() {
	// 配置日志输出格式
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
	// 配置前缀
	log.SetPrefix("order:")
	// 配置输出位置
	logFile, err := os.OpenFile("./test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		log.Panic("打开日志文件异常")
	}
	log.SetOutput(logFile)
}

func main() {
	log.Println("测试")
}

output result

Running the program will create a test.logfile with the following content:

order:2022/11/23 15:46:56 test.go:22: 测试

You can run it several times, modify the content output in running main, and observe the effect.

Standard library log log

The log package provides a simple log function. A structure is defined in the package Logger, and the structure has some methods to implement the log function.

Logger structure

type Logger struct {
    mu        sync.Mutex // ensures atomic writes; protects the following fields
    prefix    string     // prefix on each line to identify the logger (but see Lmsgprefix)
    flag      int        // properties
    out       io.Writer  // destination for output 
    buf       []byte     // for accumulating text to write 
    isDiscard int32      // atomic boolean: whether out == io.Discard
}

mu: It is a mutex to ensure the atomicity of log write operations

prefix: prefix for logs

flag: format of log input

out: The target of the output, for example: console, or file.

buf: a buffer that improves text writing speed

isDiscard: a flag, whetherout==io.Discard

log output format

The output format of the log can be controlled by the flag tag, and the constants that can be used are as follows:

const (
    Ldate         = 1 << iota     // the date in the local time zone: 2009/01/23
    Ltime                         // the time in the local time zone: 01:23:23
    Lmicroseconds                 // microsecond resolution: 01:23:23.123123.  assumes Ltime.
    Llongfile                     // full file name and line number: /a/b/c/d.go:23
    Lshortfile                    // final file name element and line number: d.go:23. overrides Llongfile
    LUTC                          // if Ldate or Ltime is set, use UTC rather than the local time zone
    Lmsgprefix                    // move the "prefix" from the beginning of the line to before the message
    LstdFlags     = Ldate | Ltime // initial values for the standard logger
)

For example, Ldate | Ltimeor LstdFlags, the output log format is as follows:

2009/01/23 01:23:23 message

For example, Ldate | Ltime | Lmicroseconds | Llongfile, the output log format is as follows:

2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message

Log prefix configuration

func Prefix() string  // 返回日志的前缀配置
func SetPrefix(prefix string)  // 设置日志前缀

Log output location configuration

func SetOutput(w io.Writer) {
	std.SetOutput(w)
}

The output location is an Writerinterface, which means that any class that implements the interface can be used, it can be the standard output to the console, or it can be a file, as we showed in the example at the beginning.

Log stack call depth setting

package main

import (
	"log"
)

func main() {
	logger := log.Default()
	logger.SetFlags(log.Llongfile)
	logger.Output(0, "0 calldepth")
	logger.Output(1, "1 calldepth")
	logger.Output(2, "2 calldepth")
}

operation result

D:/Environment/go1.19.3/src/log/log.go:185: 0 calldepth
D:/Document/learn/test.go:11: 1 calldepth                   
D:/Environment/go1.19.3/src/runtime/proc.go:250: 2 calldepth

instantiation of the log

The statements related to instantiation are:

func New(out io.Writer, prefix string, flag int) *Logger {
	l := &Logger{out: out, prefix: prefix, flag: flag}
	if out == io.Discard {
		l.isDiscard = 1
	}
	return l
}

var std = New(os.Stderr, "", LstdFlags)

func Default() *Logger { return std }

example

package main

import (
	"log"
	"os"
)

func TestLogger() {
	var (
		logger = log.New(os.Stderr, "logger: ", log.Lshortfile)
	)
	logger.Print("我就试试不进去")
}

func main() {
	TestLogger()
}

operation result

logger: test.go:17: 我就试试不进去

Log output method

Pure print log

Print[f|ln]

Print the log and throw a panic exception

Panic[f|ln]

Print the log, force the end of the program ( os.Exit(1)), deferthe function will not be executed

Fatal[f|ln]

example

package main

import (
	"fmt"
	"log"
)

func TestLogPrint() {
	//纯粹就是打印日志而已
	log.Printf("%s\n", "TestLogPrintf")
	log.Println("TestLogPrintln")

}

func TestLogPanic() {
	defer fmt.Println("Panic defer")
	log.Panicln("TestLogPanic")
	//运行后发现defer 被执行了,因此panic是等到函数执行完才结束
}

func TestLogFatal() {
	defer fmt.Println("Panic Fatal")
	log.Fatalln("TestLogFatal")
	//运行后发现defer 没被执行了,fatal 是直接结束程序
}

func main() {
	TestLogPrint()
	TestLogPanic()
	// TestLogFatal()
}

operation result

implement

TestLogPrint()
TestLogPanic()
2022/11/23 16:06:11 TestLogPrintln                      
2022/11/23 16:06:11 TestLogPanic                        
Panic defer                                             
panic: TestLogPanic                                     
                                                        
                                                        
goroutine 1 [running]:                                  
log.Panicln({0xc000109f30?, 0xc000109f60?, 0x467805?})  
        D:/Environment/go1.19.3/src/log/log.go:402 +0x65
main.TestLogPanic()
        D:/Document/learn/test.go:17 +0x94
main.main()
        D:/Document/learn/test.go:29 +0x1c

Execute only TestLogFatal()

2022/11/23 16:06:31 TestLogFatal

Guess you like

Origin blog.csdn.net/qq_40790680/article/details/128971602