日志是程序中必不可少的部分,golang的日志包log相当简洁明了。
函数
log
包主要有以下三个系列的函数
// Print calls Output to print to the standard logger.
// Arguments are handled in the manner of fmt.Print.
func Print(v ...interface{}) {
std.Output(2,fmt.Sprint(v...))
}
// Fatal is equivalent to Print() followed by a call to os.Exit(1).
func Fatal(v ...interface{}) {
std.Output(2,fmt.Sprint(v...))
os.Exit(1)
}
// Panic is equivalent to Print() followed by a call to panic().
func Panic(v ...interface{}) {
s := fmt.Sprint(v...)
std.Output(2,s)
panic(s)
}
// SetPrefix sets the output prefix for the standard logger.
func SetPrefix(prefix string) {
std.SetPrefix(prefix)
}
// SetFlags sets the output flags for the standard logger.
func SetFlags(flag int) {
std.SetFlags(flag)
}
- SetPrefix:设置日志的前缀
- SetFlags:设置日志输出的抬头信息
常量
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
LstdFlags = Ldate | Ltime // 标准日志抬头信息 initial values for the standard logger
)
实例
# file: testlog.go
package main
import "log"
func init() {
# 设置日志的前缀
log.SetPrefix("TEST LOG ")
# 设置日志抬头信息
log.SetFlags(log.LstdFlags|Lshortfile)
}
func test(name string) {
log.Printf("Hello %s\n",name)
}
func main() {
test("Golang")
test("Python")
}
TEST LOG 2018/03/25 22:00:53 log.go:14: Hello Golang
TEST LOG 2018/03/25 22:00:53 log.go:14: Hello Python
注:我们一般会把日志的初始化放在init
函数中,golang在执行main
函数之前会执行init
函数
如何定制我们项目日志
实际开发过程中,我们都会把程序的日志记录在文件中,而不是直接在终端中输出,log
包中的New
函数可以创建一个新的记录器,定制我们的日志
// file: testlog_1.go
package main
import (
"os"
"log"
)
var logger *log.Logger
var f *os.File
var err error
func init() {
f,err = os.OpenFile("test.log",os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
logger.Fatal(err)
}
logger = log.New(f,"",log.LstdFlags)
logger.SetPrefix("TEST LOG ")
logger.SetFlags(log.LstdFlags|log.Lshortfile)
}
func test(name string) {
logger.Printf("Hello %s",name)
}
func main(){
test("Golang")
test("Python")
defer f.Close()
}
运行上面程序后,在当前目录下会生成test.log
文件,且文件记录了我们写进去日志
$ cat test.log
TEST LOG 2018/03/25 22:37:02 log.go:26: Hello Golang
TEST LOG 2018/03/25 22:37:02 log.go:26: Hello Python
你是不是也觉得官方的日志处理包log
没有进行很好的封装,用起来总有那么一点不顺手或者憋屈,没关系,github上有一个日志处理包go-logging
,肯定是你的菜,看看官方的例子
package main
import (
"os"
"github.com/op/go-logging"
)
var log = logging.MustGetLogger("example")
// Example format string. Everything except the message has a custom color
// which is dependent on the log level. Many fields have a custom output
// formatting too,eg. the time returns the hour down to the milli second.
var format = logging.MustStringFormatter(
`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,)
// Password is just an example type implementing the Redactor interface. Any
// time this is logged,the Redacted() function will be called.
type Password string
func (p Password) Redacted() interface{} {
return logging.Redact(string(p))
}
func main() {
// For demo purposes,create two backend for os.Stderr.
backend1 := logging.NewLogBackend(os.Stderr, 0)
backend2 := logging.NewLogBackend(os.Stderr, 0)
// For messages written to backend2 we want to add some additional
// information to the output,including the used log level and the name of
// the function.
backend2Formatter := logging.NewBackendFormatter(backend2,format)
// Only errors and more severe messages should be sent to backend1
backend1Leveled := logging.AddModuleLevel(backend1)
backend1Leveled.SetLevel(logging.ERROR,"")
// Set the backends to be used.
logging.SetBackend(backend1Leveled,backend2Formatter)
log.Debugf("debug %s",Password("secret"))
log.Info("info")
log.Notice("notice")
log.Warning("warning")
log.Error("err")
log.Critical("crit")
}
输出如下(还有颜色喔…)