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 ...
随机推荐
- 通过HttpServletRequest重写+filter 添加header
问题说明 需要做的事情比较简单,就是通过filter 重写httpservletrequest ,同时给予request 添加header 主要是通过HttpServletRequestWrapper ...
- 开源项目 04 PdfSharp
using PdfSharp.Drawing; using PdfSharp.Pdf; using System; using System.Collections.Generic; using Sy ...
- 【LA 3942】 Remember the word
题意 给定一个字符串和若干个单词,询问能把字符串分解成这些单词的方案数.比如abcd ,有单词a,b,ab,cd:就可以分解成a+b+cd或者ab+cd. 分析 trie树—>DP 代码 (感谢 ...
- 使用JS计算前一天和后一天
使用JS实现前一天和后一天 首先,我们先在html中写两个按钮来进行简单操作 <button onclick="Before()">前一天</button> ...
- 第2课第6节_Java面向对象编程_包和权限_P【学习笔记】
摘要:韦东山android视频学习笔记 1.使用package定义编译的时候存放的位置 package a.b.c.d; public class Package { public static v ...
- 单点登录(SSO)工作原理
单点登录(SSO)工作原理 一.单点登录的介绍 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次 ...
- SpringBoot——读取配置文件@Value和@Configuration比较
1.@Configuration package com.xgcd.springboot.bean; import org.springframework.boot.context.propertie ...
- 000 list与map的foreach使用
一:list的使用 1.程序 package com.jun.it.java8; import java.util.ArrayList; import java.util.List; public c ...
- typescript - 8.命名空间
基础 略. https://www.tslang.cn/docs/handbook/namespaces.html 多文件中的命名空间(一个文件分解为几个) 现在,我们把Validation命名空间分 ...
- Mac下epub电子书制作编辑器 : Sigil
官方博客:https://sigil-ebook.com github项目地址:https://github.com/Sigil-Ebook V0.9.10下载:https://github.com/ ...