查看基本使用:

package main

import (
"log"
)

type User struct {
Name string
Age int
}

func main() {
u := User{
Name: "dj",
Age: 18,
}

log.Printf("%s login, age:%d", u.Name, u.Age)
log.Panicf("Oh, system error when %s login", u.Name)
log.Fatalf("Danger! hacker %s login", u.Name)
}

​log​​​默认输出到标准错误(​​stderr​​​),每条日志前会自动加上日期和时间。如果日志不是以换行符结尾的,那么​​log​​会自动加上换行符。即每条日志会在新行中输出。

​log​​提供了三组函数:

  • ​Print/Printf/Println​​:正常输出日志;
  • ​Panic/Panicf/Panicln​​​:输出日志后,以拼装好的字符串为参数调用​​panic​​;
  • ​Fatal/Fatalf/Fatalln​​​:输出日志后,调用​​os.Exit(1)​​退出程序。

命名比较容易辨别,带​​f​​​后缀的有格式化功能,带​​ln​​后缀的会在日志后增加一个换行符。

注意,上面的程序中由于调用​​log.Panicf​​​会​​panic​​​,所以​​log.Fatalf​​并不会调用。

 

前缀:

调用log.SetPrefix为每条日志文本前增加一个前缀。例如,在上面的程序中设置Login:前缀:
package main

import (
"log"
)

type User struct {
Name string
Age int
}

func main() {
u := User{
Name: "dj",
Age: 18,
}

log.SetPrefix("Login: ")
log.Printf("%s login, age:%d", u.Name, u.Age)
}

 

选项flag:

设置选项可在每条输出的文本前增加一些额外信息,如日期时间、文件名等。

​log​​库提供了 6 个选项:

const (
Ldate = 1 << iota
Ltime
Lmicroseconds
Llongfile
Lshortfile
LUTC
)
  • ​Ldate​​​:输出当地时区的日期,如​​2020/02/07​​;
  • ​Ltime​​​:输出当地时区的时间,如​​11:45:45​​;
  • ​Lmicroseconds​​​:输出的时间精确到微秒,设置了该选项就不用设置​​Ltime​​​了。如​​11:45:45.123123​​;
  • ​Llongfile​​​:输出长文件名+行号,含包名,如​​github.com/darjun/go-daily-lib/log/flag/main.go:50​​;
  • ​Lshortfile​​​:输出短文件名+行号,不含包名,如​​main.go:50​​;
  • ​LUTC​​​:如果设置了​​Ldate​​​或​​Ltime​​,将输出 UTC 时间,而非当地时区。
package main

import (
"log"
)

type User struct {
Name string
Age int
}

func main() {
u := User{
Name: "dj",
Age: 18,
}

log.SetFlags(log.Lshortfile | log.Ldate | log.Lmicroseconds)

log.Printf("%s login, age:%d", u.Name, u.Age)
}

调用​​log.Flags()​​可以获取当前设置的选项。

 

​log​​​库还定义了一个​​Lstdflag​​​,为​​Ldate | Ltime​​,这就是我们默认的选项。

const (
LstdFlags = Ldate | Ltime
)

 

​log.New​​接受三个参数:

  • ​io.Writer​​​:日志都会写到这个​​Writer​​中;
  • ​prefix​​​:前缀,也可以后面调用​​logger.SetPrefix​​设置;
  • ​flag​​​:选项,也可以后面调用​​logger.SetFlag​​设置。

 

 

注意到,第一个参数为​​io.Writer​​​,我们可以使用​​io.MultiWriter​​​实现多目的地输出。下面我们将日志同时输出到标准输出、​​bytes.Buffer​​和文件中:

package main

import (
"bytes"
"io"
"log"
"os"
)

type User struct {
Name string
Age int
}

func main() {
u := User{
Name: "dj",
Age: 18,
}

writer1 := &bytes.Buffer{}
writer2 := os.Stdout
writer3, err := os.OpenFile("log.txt", os.O_WRONLY|os.O_CREATE, 0755)
if err != nil {
log.Fatalf("create file log.txt failed: %v", err)
}

logger := log.New(io.MultiWriter(writer1, writer2, writer3), "", log.Lshortfile|log.LstdFlags)
logger.Printf("%s login, age:%d", u.Name, u.Age)
}

 

自定义日志包:

logfer/logger.go

package logger

import (
"io"
"log"
"os"
)

const (
flag = log.Ldate | log.Ltime | log.Lshortfile
preDebug = "[DEBUG]"
preInfo = "[INFO]"
preWarn = "[WARN]"
preError = "[ERROR]"
)

var (
logFile io.Writer
debugLogger *log.Logger
infoLogger *log.Logger
warnLogger *log.Logger
errorLogger *log.Logger
defaultLogFile = "web.log"
)

func init(){
var err error
logFile, err = os.OpenFile(defaultLogFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if err != nil {
defaultLogFile = "./web.log"
logFile, err = os.OpenFile(defaultLogFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if err != nil {
log.Fatalf("create log file err %+v", err)
}
}

debugLogger = log.New(logFile, preDebug, flag)
infoLogger = log.New(logFile, preInfo, flag)
warnLogger = log.New(logFile, preWarn, flag)
errorLogger = log.New(logFile, preError, flag)

}

func Debugf(format string, v ...interface{}){
debugLogger.Printf(format, v...)
}

func Infof(format string, v ...interface{}){
infoLogger.Printf(format, v...)
}

func Warnf(format string, v ...interface{}){
warnLogger.Printf(format, v...)
}

func Errorf(format string, v ...interface{}){
errorLogger.Printf(format, v...)
}

func SetOutputPath(path string) {
var err error
logFile, err = os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if err != nil {
log.Fatalf("create log file err %+v", err)

}
debugLogger = log.New(logFile, preDebug, flag)
infoLogger = log.New(logFile, preInfo, flag)
warnLogger = log.New(logFile, preWarn, flag)
errorLogger = log.New(logFile, preError, flag)
}

使用方式:

errStr := "this is a error"
logger.Debugf("hello, %s", errStr)
logger.Infof("hello, %s", errStr)
logger.Warnf("hello, %s", errStr)
logger.Errorf("hello, %s", errStr)