使用

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 提供了两种默认的日志输出格式, TextFormatterJSONFormatter.上面的示例使用的就是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类同,这里就不再赘述。总之logrusformatter实现比较简单,常用参数也在注释里进行了详细的说明。

自定义 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的更多相关文章

  1. logrus 剖析之滚动日志

    在实际开发过程中,为了节省磁盘,日志需要按照时间或者大小维度进行切割分成多分,归档过期的日志,删除久远的日志.这个就是在日常开发中经常遇见的日志滚动(log rotation) 那么在 logrus ...

  2. logrus 剖析之 hook

    logrus 通过实现 Hook接口扩展 hook 机制,可以根据需求将日志分发到任意的存储介质, 比如 es, mq 或者监控报警系统,及时获取异常日志.可以说极大的提高了日志系统的可扩展性. ho ...

  3. logrus日志框架

    目录 logrus介绍 logrus配置 日志打印 HOOK机制 Gin日志 Fatal处理 线程安全 logrus介绍 golang标准库的日志框架非常简单,仅仅提供了print,panic和fat ...

  4. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetad ...

  5. WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化

    原文:WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制 ...

  6. WCF技术剖析之一:通过一个ASP.NET程序模拟WCF基础架构

    原文:WCF技术剖析之一:通过一个ASP.NET程序模拟WCF基础架构 细算起来,已经有好几个月没有真正的写过文章了.近半年以来,一直忙于我的第一本WCF专著<WCF技术剖析>的写作,一直 ...

  7. logrus学习笔记

    logrus源码:https://github.com/sirupsen/logrus 1.logrus.Entry结构 1.1 类型 type Entry struct { Logger *Logg ...

  8. Go中的日志及第三方日志包logrus

    有别的语言使用基础的同学工作中都会接触到日志的使用,Go中自然也有log相关的实现.Go log模块主要提供了3类接口,分别是 "Print .Panic .Fatal ",对每一 ...

  9. Go第三方日志库logrus

    日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...

随机推荐

  1. 通过HttpServletRequest重写+filter 添加header

    问题说明 需要做的事情比较简单,就是通过filter 重写httpservletrequest ,同时给予request 添加header 主要是通过HttpServletRequestWrapper ...

  2. 开源项目 04 PdfSharp

    using PdfSharp.Drawing; using PdfSharp.Pdf; using System; using System.Collections.Generic; using Sy ...

  3. 【LA 3942】 Remember the word

    题意 给定一个字符串和若干个单词,询问能把字符串分解成这些单词的方案数.比如abcd ,有单词a,b,ab,cd:就可以分解成a+b+cd或者ab+cd. 分析 trie树—>DP 代码 (感谢 ...

  4. 使用JS计算前一天和后一天

    使用JS实现前一天和后一天 首先,我们先在html中写两个按钮来进行简单操作 <button onclick="Before()">前一天</button> ...

  5. 第2课第6节_Java面向对象编程_包和权限_P【学习笔记】

    摘要:韦东山android视频学习笔记  1.使用package定义编译的时候存放的位置 package a.b.c.d; public class Package { public static v ...

  6. 单点登录(SSO)工作原理

    单点登录(SSO)工作原理 一.单点登录的介绍 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次 ...

  7. SpringBoot——读取配置文件@Value和@Configuration比较

    1.@Configuration package com.xgcd.springboot.bean; import org.springframework.boot.context.propertie ...

  8. 000 list与map的foreach使用

    一:list的使用 1.程序 package com.jun.it.java8; import java.util.ArrayList; import java.util.List; public c ...

  9. typescript - 8.命名空间

    基础 略. https://www.tslang.cn/docs/handbook/namespaces.html 多文件中的命名空间(一个文件分解为几个) 现在,我们把Validation命名空间分 ...

  10. Mac下epub电子书制作编辑器 : Sigil

    官方博客:https://sigil-ebook.com github项目地址:https://github.com/Sigil-Ebook V0.9.10下载:https://github.com/ ...