logrus 剖析之 formatter
使用
logrus 通过 formatter 来定义输出日志的格式,具体例子如下:
package main
import (
log "github.com/Sirupsen/logrus"
)
func main() {
formatter := &log.TextFormatter{
// 不需要彩色日志
DisableColors: true,
// 定义时间戳格式
TimestampFormat: "2006-01-02 15:04:05",
}
log.SetFormatter(formatter)
log.Printf("hello world")
}
打印的日志内容如下:
time="2019-11-07 17:41:20" level=info msg="hello world"
说明:
- time: 日志的打印时间
- level: 日志的等级
- msg: 日志内容
分析
本身 formatter 是接口类型,只要实现该结构我们就可以自定义日志输出格式:
// Any additional fields added with `WithField` or `WithFields` are also in
// `entry.Data`. Format is expected to return an array of bytes which are then
// logged to `logger.Out`.
type Formatter interface {
Format(*Entry) ([]byte, error)
}
logrus 提供了两种默认的日志输出格式, TextFormatter和JSONFormatter.上面的示例使用的就是TextFormatter.
TextFormatter
type TextFormatter struct {
// Set to true to bypass checking for a TTY before outputting colors.
ForceColors bool
//不使用彩色日志
DisableColors bool
// Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/
EnvironmentOverrideColors bool
// 是否打印时间戳
DisableTimestamp bool
// Enable logging the full timestamp when a TTY is attached instead of just
// 是否按照时间戳格式打印,置为false则只打印从程序启动到打印日志的时间差(单位:秒)
FullTimestamp bool
// 时间戳格式
TimestampFormat string
// 设置 fields 不排序
DisableSorting bool
// 设置 fields 的排序规则
SortingFunc func([]string)
// Disables the truncation of the level text to 4 characters.
DisableLevelTruncation bool
// QuoteEmptyFields will wrap empty fields in quotes if true
QuoteEmptyFields bool
// 是否打印日志到终端
isTerminal bool
// fieldMap
// As an example:
// formatter := &TextFormatter{
// FieldMap: FieldMap{
// FieldKeyTime: "@timestamp",
// FieldKeyLevel: "@level",
// FieldKeyMsg: "@message"}}
FieldMap FieldMap
// 设置 func 和 file 这两个 field的输出格式
CallerPrettyfier func(*runtime.Frame) (function string, file string)
terminalInitOnce sync.Once
}
TextFormatter 实现 Formatter接口
// Format renders a single log entry
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
data := make(Fields)
for k, v := range entry.Data {
data[k] = v
}
// prefixFieldClashes 删除默认的 4 个 field,防止冲突(msg, level, time, logrus_error)
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
keys := make([]string, 0, len(data))
for k := range data {
keys = append(keys, k)
}
// 拼接待打印日志的各个元素
var funcVal, fileVal string
// 拼接元素过程省略 ...
f.terminalInitOnce.Do(func() { f.init(entry) })
// 修改时间戳
timestampFormat := f.TimestampFormat
if timestampFormat == "" {
timestampFormat = defaultTimestampFormat
}
// 以下省略 ...
// 打印换行符
b.WriteByte('\n')
return b.Bytes(), nil
}
JSONFormatter
// JSONFormatter formats logs into parsable json
type JSONFormatter struct {
// TimestampFormat sets the format used for marshaling timestamps.
TimestampFormat string
// DisableTimestamp allows disabling automatic timestamps in output
DisableTimestamp bool
// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
DataKey string
// FieldMap allows users to customize the names of keys for default fields.
// As an example:
// formatter := &JSONFormatter{
// FieldMap: FieldMap{
// FieldKeyTime: "@timestamp",
// FieldKeyLevel: "@level",
// FieldKeyMsg: "@message",
// FieldKeyFunc: "@caller",
// },
// }
FieldMap FieldMap
// CallerPrettyfier can be set by the user to modify the content
// of the function and file keys in the json data when ReportCaller is
// activated. If any of the returned value is the empty string the
// corresponding key will be removed from json fields.
CallerPrettyfier func(*runtime.Frame) (function string, file string)
// PrettyPrint will indent all json logs
PrettyPrint bool
}
JSONFormatter的实现方式与TextFormatter类同,这里就不再赘述。总之logrus的formatter实现比较简单,常用参数也在注释里进行了详细的说明。
自定义 Formatter
这里我们自定义一个 formatter,这个 formatter会在打印的日志前后分别加上前缀和后缀。
package main
import (
"bytes"
"fmt"
log "github.com/Sirupsen/logrus"
)
func main() {
// 初始化自定义 formatter
formatter := &MyFormatter{
Prefix: "prefix",
Suffix: "suffix",
}
log.SetFormatter(formatter)
log.Infoln("hello world")
}
// MyFormatter 自定义 formatter
type MyFormatter struct {
Prefix string
Suffix string
}
// Format implement the Formatter interface
func (mf *MyFormatter) Format(entry *log.Entry) ([]byte, error) {
var b *bytes.Buffer
if entry.Buffer != nil {
b = entry.Buffer
} else {
b = &bytes.Buffer{}
}
// entry.Message 就是需要打印的日志
b.WriteString(fmt.Sprintf("%s - %s - %s", mf.Prefix, entry.Message, mf.Suffix))
return b.Bytes(), nil
}
打印结果如下:
prefix - hello world - suffix
logrus 剖析之 formatter的更多相关文章
- logrus 剖析之滚动日志
在实际开发过程中,为了节省磁盘,日志需要按照时间或者大小维度进行切割分成多分,归档过期的日志,删除久远的日志.这个就是在日常开发中经常遇见的日志滚动(log rotation) 那么在 logrus ...
- logrus 剖析之 hook
logrus 通过实现 Hook接口扩展 hook 机制,可以根据需求将日志分发到任意的存储介质, 比如 es, mq 或者监控报警系统,及时获取异常日志.可以说极大的提高了日志系统的可扩展性. ho ...
- logrus日志框架
目录 logrus介绍 logrus配置 日志打印 HOOK机制 Gin日志 Fatal处理 线程安全 logrus介绍 golang标准库的日志框架非常简单,仅仅提供了print,panic和fat ...
- WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)
原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetad ...
- WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化
原文:WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制 ...
- WCF技术剖析之一:通过一个ASP.NET程序模拟WCF基础架构
原文:WCF技术剖析之一:通过一个ASP.NET程序模拟WCF基础架构 细算起来,已经有好几个月没有真正的写过文章了.近半年以来,一直忙于我的第一本WCF专著<WCF技术剖析>的写作,一直 ...
- logrus学习笔记
logrus源码:https://github.com/sirupsen/logrus 1.logrus.Entry结构 1.1 类型 type Entry struct { Logger *Logg ...
- Go中的日志及第三方日志包logrus
有别的语言使用基础的同学工作中都会接触到日志的使用,Go中自然也有log相关的实现.Go log模块主要提供了3类接口,分别是 "Print .Panic .Fatal ",对每一 ...
- Go第三方日志库logrus
日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...
随机推荐
- 超级好用的excel导出方法,比phpexcel快n倍,并且无乱码
public function exportToExcel($filename, $tileArray=[], $dataArray=[]){ ini_set('memory_limit','512M ...
- Loj刷题记录
又是一年云参营. 所以一起刷省选题吧. LOJ2028 「SHOI2016」随机序列 题目链接. 简要社论 发现+和-可以互相抵消,于是有贡献的时候一段前缀的乘积.设\(s[i]=\prod_{j=1 ...
- 【luoguP4544】[USACO10NOV]购买饲料Buying Feed
题目链接 首先把商店按坐标排序 \(dp_{i,j}\)表示前i个商店买了j吨饲料并运到终点的花费,二进制拆分优化转移 #include<algorithm> #include<io ...
- hotspot编译
"AA=="1",==", /usr/bin/make -s VERBOSE="-s" LOG_LEVEL="warn" ...
- 使用良好的自定义X264编码,取得极佳质量!《转》
原帖地址:http://www.xspliter.com/forum.php?mod=viewthread&tid=447 一般直播时使用A设定即可.你尝试设置并找出你最满意的设定 A为最需最 ...
- qtcreator 添加 cppreference 离线文档
https://en.cppreference.com/w/File:qch_book_20190607.zip 下载后放到 D:\Qt\Qt5.10.0\Docs\Qt-5.10.0目录下, 并在q ...
- postgres安装pg_buffercache扩展
1.查看是否安装了pg_buffercache postgres=# \dx List of installed extensions Name | Version | Schema | Descri ...
- android -------- Base64 加密解密算法
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法.可查看RFC2045-RFC2049,上面有MIME的详细规范. Ba ...
- 013 Enhancer创建动态代理
在上一章使用了Enhancer,没有仔细说明代理的问题,在这一章进行详细的说明. 原本想使用cf包的,后来发现使用framework包下的包也没有问题,程序中就一直使用framework中的类. 一: ...
- oracle系列九 SET运算符查询
将多个查询用 SET 操作符连接组成一个新的查询 UNION/UNION ALL INTERSECT MINUS 排序:ORDER BY UNION 操作符 UNION 操作符返回两个查询的结果集的并 ...