Go常用库-日志Logrus

写在前面:

Logrus版本: v1.4.2

logrus相当于标准库log包的加强版,是目前最流行的日志库.它在完全兼容原生方法的基础上,增加了格式化日志的能力,简单易用,使得日志更为工整.其源码代码量并不大,通读一下便于后续理解使用.

time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009

一. Logrus官网-并没有

Logrus的特点就是使用简单,并不需要特别搭个网站说明,文档就是项目的readme.
sirupsen/logrus: Structured, pluggable logging for Go. - GitHub
中文版的简单介绍:
Logrus日志框架

二. 使用+说明:

logrus日志使用详解
Go进阶10:logrus日志使用教程
源码中 example_**.go, 和readme中说明的一样的,只是更加完整.

三. Logrus源码(v1.4.2)

1. exported.go

这是包的入口,在这里定义了包级变量std(实际是logger)作为标准库log替代,并声明了包方法WithField(),Debug()等供外部调用.实际就是调用logger结构的方法.

2. logrus.go和logger.go

logrus.go是包的类型说明文件,定义了Fields是map[string]interface{}类型;Level的枚举;StdLogger和FieldLogger两个接口.
logger.go是整个包的核心,当我们调用日志方法时候,就是它在工作.当然它作为包级变量也不是自己去实干,而是根据参数newEntry出来,让Entry实际完成写日志的动作.

3. entry.go

Entry结构是真正干活的,它保持需要记录日志的要素,包括通用(Time,Level)和自定义(Data)

type Entry struct {
    Logger *Logger

    // Contains all the fields set by the user.
    Data Fields

    // Time at which the log entry was created
    Time time.Time

    // Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
    // This field will be set on entry firing and the value will be equal to the one in Logger struct field.
    Level Level

    // Calling method, with package name
    Caller *runtime.Frame

    // Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
    Message string

    // When formatter is called in entry.log(), a Buffer may be set to entry
    Buffer *bytes.Buffer

    // Contains the context set by the user. Useful for hook processing etc.
    Context context.Context

    // err may contain a field formatting error
    err string
}

其核心方法是log(),里面把打印的内容放入buffer,然后调用entry.write(),写入Logger.Out.(由于Logger.Out(通常是日志文件)可能会并冲突,因而write()方法是有进行加锁的.)

P.S.1. 从log()方法可以看出,entry至少有Time,Level,Message三部分,这样就能格式化出基本的格式.
P.S.2. GO并没有java的Trace()机制,要实现打印调用栈就要用到runtime.Frame,Logrus使用getCaller()方法跟踪函数的调用情况,从而实现调用栈的打印.

4. formatter.go以及son_formatter.go和text_formatter.go实现

formatter是logrus扩展处,它从Entry构造出需要打印的data(实际就是Map)结构,再转换为实际输出的[]byte

Logrus提供了两种标准实现:

  • JSON主要就是用Encoder完成Json的序列化
  • Text复杂点,特别如果设置corlored,还要调用printColored()实现彩色字体.(这个真没细看...)

5. hooks.go和hooks目录

logrus实现了Hook机制,在entry的log()方法的write方法前,会调用entry.fireHooks()执行钩子函数.这个时候会把entry传递给Hook,让钩子进行自定义操作.
hooks.go定义了包变量LevelHooks(根据日志级别登记所有Hooks),和Hook接口:

type Hook interface {
    Levels() []Level
    Fire(*Entry) error
}

hooks目录定义了一个系统钩子,其writer为*syslog.Writer,这样使用这个Hook,就会在各种日志级别也写一份日志到这个Writer中.Logrus官方整理了各种Hook:
https://github.com/sirupsen/logrus/wiki/Hooks
例如KafkaLogrus可以同步Log到kafaka,Logstash可以同步Log到ELK

6. 其他

  • terminal_check_*.go: 检测各种操作系统是否有控制台.
  • writter.go: 对io.Writer的实现,使得Logrus能够传给其他Lib用,如http.Server或者替换系统的标准输出:
log.SetOutput(logger.Writer())

四.其他推荐阅读文章

Logrus -- Go 的结构化 logger

Golang logrus的高级配置(hook, logrotate)

Logrus源码阅读(1)--基本用法

Logrus源码阅读(2)--logrus生命周期

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容

  • 上一篇介绍logrus的基本用法, 本篇文章介绍logrus的整个生命周期 从上面这个简单的例子, 追踪logru...
    HHFCodeRv阅读 2,209评论 1 2
  • 本文转载自姜总 golang日志库 golang标准库的日志框架非常简单,仅仅提供了print,panic和fat...
    哆啦在这A梦在哪阅读 7,927评论 4 9
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 2,699评论 0 3
  • 梨花受露湿香尘,飞絮频沾满袖春。 一簇年华三处镜,此间风景最留人。 ①镜:这里指镜头、照相机。
    侧帽风流阅读 2,729评论 69 81
  • 孙子从蹒跚学步时,就喜欢上了做饭。他会让大人给他拿一口锅放到地上,然后在锅里随便放上一些东西,再拿一把铲子,他的小...
    心如莲花_fea1阅读 623评论 4 2