golang日志库之log
查看基本使用:
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)
golang日志库之log的更多相关文章
- C++ 日志库 boost::log 以及 glog 的对比
日志能方便地诊断程序原因.统计程序运行数据,是大型软件系统必不可少的组件之一.本文将从设计上和功能上对比 C++ 语言常见的两款日志库: boost::log 和 google-glog . 设计 b ...
- golang 日志模块(log)
log 日志 log 模块可以自定义log 对象, 也可以使用log默认对象的日志方法 func New 创建log对象 func New(out io.Writer, prefix string, ...
- golang日志库之glog使用问题总结
1. 日志默认输出路径为临时路径,可通过执行命令时带上 -log_dir="路径",指定输出,但路径必须已存在,源码如下,日志文件会生成两个 .INFO等后缀是符号链接文件,另一个 ...
- Golang 标准库log的实现
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://gotaly.blog.51cto.com/8861157/1406905 前 ...
- golang常用库包:log日志记录-uber的Go日志库zap使用详解
Go 日志记录库:uber-go 的日志操作库 zap 使用 一.简介 zap 是 uber 开源的一个高性能,结构化,分级记录的日志记录包. go1.20.2 zap v1.24.0 zap的特性 ...
- golang常用库:日志记录库-logrus使用
介绍 logrus 它是一个结构化.插件化的日志记录库.完全兼容 golang 标准库中的日志模块.它还内置了 2 种日志输出格式 JSONFormatter 和 TextFormatter,来定义输 ...
- Golang:手撸一个支持六种级别的日志库
Golang标准日志库提供的日志输出方法有Print.Fatal.Panic等,没有常见的Debug.Info.Error等日志级别,用起来不太顺手.这篇文章就来手撸一个自己的日志库,可以记录不同级别 ...
- Golang一日一库之 日志库 zap
简介 在开发过程中 会使用到日志库去记录错误的日志,尤其是golang中 有无穷无尽的error 如果不记录,当你的代码出错,就无从排错了. zap 是开源的 Go 高性能日志库 主要有以下特点: 支 ...
- C/C++log日志库比较
事实上,在C的世界里面没有特别好的日志函数库(就像Java里面的的log4j,或者C++的log4cxx).C程序员都喜欢用自己的轮子.printf就是个挺好的轮子,但没办法通过配置改变日志的格式或者 ...
- [译]如何禁止Requests库的log日志信息呢?
原文来源: https://stackoverflow.com/questions/11029717/how-do-i-disable-log-messages-from-the-requests-l ...
随机推荐
- kubernetes重新初始化“[ERROR DirAvailable--var-lib-etcd]”
[root@master01 ~]# kubeadm init --config /root/kubeadm-config.yaml --upload-certs [init] Using Kuber ...
- 小tips:xml文件转为html表格展示示例
books.xml文件格式如下: <?xml version="1.0" encoding="UTF-8"?> <xbrl xmlns=&qu ...
- Facebook Ads – 笔记
前言 记入一些小东西 参考 YouTube – 这是第一次广告投放回报做到11倍!Facebook广告高广告投资回报2023年终极策略密码分享 价值阶梯 先卖便宜 value 低的东西给客户,甚至免费 ...
- Windows右下角时间显示具体星期
事件起因: 有时候脑子不清楚,过着过着就会忘记今天是星期几,错过一些重要事情,于是乎就想看看Windows右下角能不能显示到具体星期,果然在查了资料之后这个需求可以达成 解决办法: 控制面板 - 日期 ...
- 【赵渝强老师】Kubernetes平台中日志收集方案
一.K8s整体日志收集方案 整体的日志收集方案,如下图所示: Filebeat是本地文件的日志数据采集器,可监控日志目录或特定日志文件(tail file),并将它们转发给Elasticsearch或 ...
- 获取form提交的返回值
获取form提交的返回值 HTML代码如下: <form action="" method="post" enctype="multipart/ ...
- python:批量删除指定文件目录中多个文件
#coding:utf-8# 任务需要,需要删除多余的文件,手动删除太麻烦,几行python搞定 import os from glob import glob path = r"/medi ...
- iOS工厂模式使用小结
一.什么是工厂方法? 正式的解释是:在基类中定义创建对象的一个接口,让子类决定实例化哪个类.工厂方法让一个类的实例化延迟到子类中进行.工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好 ...
- 图片的穿透效果 -- pointer-events: none
使用场景:当我们需要选择上传文件的时候,图片把input输入框覆盖在上面,点击的时候不能出发input输入框所以要给图片设置穿透属性 : 具体代码: #image { position: fixed; ...
- slot原理
vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽 : 作用:再不确定的内容位置占位,在子组件内使用 slot 标签写占位的内容 : 插槽的分类 : 默认插槽: 具名插槽:使用 ...