Go log

JunChow520 · · 559 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一般而言日志可分为事件日志和消息日志两种

  • 事件日志记录发生在系统运行过程中的事件,用来审计操作、诊断问题等。对理解复杂系统的运行非常关键。
  • 消息日志被应用在比如即时通信中,用来记录来往的消息。

标准的日志定义在IETF中,会记录时间、地点、参与者、起因、简要经过等信息。

日志记录一般格式:[时间][日志级别][地点][参与者][事件][起因]

对于系统日志一般还会定义严重性等级(Severity Level)用来标识该条日志记录的紧要程度

紧要程度 日志级别
0 EMERGENCY
1 ALERT
2 CREITICAL
3 ERROR
4 WARNING
5 NOTICE
6 INFORMATION
7 DEBUG

log

Golang内置了标准的log日志库

package main

import "log"

type User struct {
    Id   int
    Name string
}

func main() {
    user := User{Id: 1, Name: "admin"}
    log.Printf("id = %v, name = %v", user.Id, user.Name) 
}
2021/03/31 22:18:33 id = 1, name = admin

Golang默认的日志记录分为两部分,前面是事件发生的时间,后面是事件记录。

log日志记录器默认是多goroutine安全的,多个goroutine可以同时调用来自一个日志记录器的输出函数,而不会发生写冲突。

日志输出

  • log日志库默认会输出日志到标准错误stderr
  • log日志库会将每条日志前自动添加上日期和时间
  • 若日志不是以换行符为结尾,则会自动补上换行符。

log日志库提供了三组函数用于输出日志

输出 格式化 换行 描述
log.Print log.Printf log.Println 正常输出日志
log.Panic log.Panicf log.Panicln 输出日志与相关调用信息后退出程序
log.Fatal log.Fatalf log.Fatalln 输出日志后退出程序os.Exit(1)

设置前缀

  • 调用log.SetPrefix会为每条日志文本前添加一个前缀
user := User{Id: 1, Name: "admin"}

log.SetPrefix("[ERROR] ")
log.Printf("id = %v, name = %v", user.Id, user.Name)
[ERROR] 2021/03/31 22:32:31 id = 1, name = admin

设置选项

  • 调用log.SetFlags为输出的日志添加选项,可同时设置多个,多个|分割。
  • 设置选项可为每条日志输出的文本前增加额外信息
选项 描述
Ldate 输出当地时区日期
Ltime 输出当地时区时间
Lmicroseconds 输出时间精确到微秒
Llongfile 输出全文件名和行号,包含包名。
Lshortfile 输出当前文件名加行号,不包含报名。
LUTC 若已设置Ldate或Ltime则输出UTC时间,而非当地时区。
user := User{Id: 1, Name: "admin"}

log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Llongfile | log.LUTC)
log.SetPrefix("[ERROR] ")

log.Printf("id = %v, name = %v", user.Id, user.Name)
[ERROR] 2021/03/31 14:31:21.368463 D:/go/project/example/main.go:14: id = 1, name = admin

日志记录器

  • logger是对log的简单封装,使用logger可以使日志记录更加便捷。
func log.New(out io.Writer, prefix string, flag int) *Logger
参数 类型 描述
out io.Writer 设置日志数据接入的目的地
prefix string 每行日志前缀字符串
flag int 设置日志记录选项
user := User{Id: 1, Name: "admin"}

logger := log.New(os.Stdout, "[DEBUG] ", log.Ldate|log.Ltime|log.Lshortfile)
logger.Printf("id = %v, name = %v", user.Id, user.Name)
[DEBUG] 2021/03/31 23:00:03 main.go:17: id = 1, name = admin

例如:将错误记录到日志同时打印到文件

package main

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

var (
    Error *log.Logger
)

func init() {
    filename := "error.log"
    file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        log.Fatalln(err)
    }
    out := io.MultiWriter(file, os.Stderr)

    Error = log.New(out, "[ERROR] ", log.Ldate|log.Ltime|log.Llongfile)
}

func main() {
    user := &struct {
        Id   int
        Name string
    }{
        Id:   1,
        Name: "admin",
    }

    Error.Printf("id = %v, name = %v", user.Id, user.Name)
}

创建文件

file,err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
选项 描述
os.O_CREATE 若文件不存在则创建新文件
os.O_WRONLY 打开文件的读写权限
os.O_APPEND 写入数据时采用追加而非覆盖的方式

例如:

  • 指定日志文件保存路径,若目录不存在则创建。
  • 向指定目录的日志文件内写入日志,同时打印到标准输出。
package main

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

var (
    Error *log.Logger
)

//MakeDir 创建目录
func MakeDir(dir string) (bool, error) {
    //判断文件是否存在
    _, err := os.Stat(dir)
    if err == nil {
        return true, nil
    }
    //递归创建文件夹
    err = os.MkdirAll(dir, 0755)
    if err != nil {
        return false, err
    }
    return true, nil
}

func init() {
    dir := "./runtime/log/"
    filename := "error.log"
    filepath := dir + filename

    ok, err := MakeDir(dir)
    if err != nil && !ok {
        panic(err)
    }

    file, err := os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        log.Fatalln(err)
    }

    out := io.MultiWriter(file, os.Stderr)
    Error = log.New(out, "[ERROR] ", log.Ldate|log.Ltime|log.Llongfile)
}

func main() {
    user := &struct {
        Id   int
        Name string
    }{
        Id:   1,
        Name: "admin",
    }

    Error.Printf("id = %v, name = %v", user.Id, user.Name)
}

日志级别

紧急程度 级别名称 级别方法 日志前缀 颜色
0 fatal Fatal/Fatalf [FATAL] 红色背景色
1 error Error/Errorf [ERROR] 红色前景色
2 warn Warn/Warnf/Warningf [WARN] 杨红背景色
3 info Info/Infof [INFO] 请求前景色
4 debug Debug/Debugf [DEBUG] 黄色前景色

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:JunChow520

查看原文:Go log

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

559 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传