logrus学习笔记
logrus源码:https://github.com/sirupsen/logrus
1.logrus.Entry结构
1.1 类型
type Entry struct {
Logger *Logger // 指向Logger对象
Data Fields // 包含用户设置的所有字段,Fields结构:type Fields map[string]interface{}
Time time.Time // log entry创建时间
Level Level // 可以记录的日志级别为Trace, Debug, Info, Warn, Error, Fatal or Panic
Caller *runtime.Frame // 带包名的调用时方法,每条日志中记录文件名、函数和行号
Message string // 要记录的消息
Buffer *bytes.Buffer // 当在entry.log方法中调用formatter接口实现的方法,Buffer才会被使用到
err string // 用于记录字段格式化错误
}
1.2 方法
1. func NewEntry(logger *Logger) *Entry
功能说明:创建一个新的Entry对象,接口对包外开放
流程分析:传入Logger对象,初始化Entry.Logger和Entry.Data成员
2. func (entry *Entry) String() (string, error)
功能说明:将Entry中的数据序列化成string,并返回
流程分析:调用entry.Logger.Formatter.Format方法,其中Formatter是一个接口,类型定义如下:
type Formatter interface {
Format(*Entry) ([]byte, error)
}
Logger.Formatter在logrus/logger.go中默认初始化为TextFormatter,见方法“func New() *Logger”,或者
使用方法Logger.SetFormatter初始化,常用的Formatter有:TextFormatter、JSONFormatter,也可自定义实现Formatter接口
3. func (entry *Entry) WithError(err error) *Entry
功能说明:添加err字段到Entry.Data中,返回一个新的entry对象
流程分析:详解见Entry.WithField
4. func (entry *Entry) WithField(key string, value interface{}) *Entry
功能说明:向Entry.Data字段追加{key, value}字段,并返回一个新的Entry对象
流程分析:详解见Entry.WithFields
5. func (entry *Entry) WithFields(fields Fields) *Entry
功能说明:向Entry.Data中依次追加fields中包含的若干个字段,其中Fields结构为type Fields map[string]interface{}
流程分析:
1.先将Entry.Data中原有的元素添加至临时的data变量中
2.循环添加fields中元素至data中,若添加失败,则将添加的失败信息追加到Entry.err
3.返回一个新的Entry对象
6. func (entry *Entry) WithTime(t time.Time) *Entry
功能说明:修改Entry.Time,并返回一个新的Entry对象
流程分析:无
7. func (entry Entry) log(level Level, msg string)
功能说明:日志处理的核心部分
流程分析:
1.初始化entry的Time、Level、Message字段
2.如果entry.Logger.ReportCaller为true,则获取运行时调用者信息,初始化entry.Caller字段
3.调用entry.fireHooks方法,处理所有entry.Logger上注册的Hook,详解见entry.fireHooks方法
4.给entry.Buffer初始化一个*bytes.Buffer对象,以备entry.write中间隔使用,详解见entry.write方法Entry.Caller类型为*runtime.Frame,保存运行时调用者信息,包括文件名、方法名、方法行号等。
系统默认的logger为std,Logger.ReportCaller字段默认为false,可使用Logger.SetReportCaller打开
8. func (entry *Entry) fireHooks()
功能说明:处理当前一条日志所有的Hook
流程分析:调用entry.Logger.Hooks.Fire方法,实际是处理entry.Level级别对应的所有Hook,详解见Logger.Hooks.Fire方法
9. func (entry *Entry) write()
功能说明:没有Hook的情况下,日志默认处理流程
流程分析:
1.使用entry.Logger.Formatter.Format格式化日志,返回一个序列化的日志数据
2.使用entry.Logger.Out.Write写日志,系统默认Logger使用os.Stderr写日志
10. func (entry *Entry) Log(level Level, args ...interface{})
功能说明:不同级别日志fmt.Sprint方式的通用处理方法
流程分析:
1.如果当前待写的日志级别小于Logger的级别,才会调用entry.log
2.使用fmt.Sprint格式化用户的日志
11. func (entry *Entry) Trace(args ...interface{})
功能说明:entry的TraceLevel级别以fmt.Sprint方式写日志方法,其它级别雷同
流程分析:无
12. func (entry *Entry) Logf(level Level, format string, args ...interface{})
功能说明:不同级别日志以fmt.Sprintf方式的通用处理方法
流程分析:
1.如果当前待写的日志级别小于Logger的级别,才会调用entry.log
2.使用fmt.Sprintf格式化用户的日志
13. func (entry *Entry) Tracef(args ...interface{})
功能说明:entry的TraceLevel级别以fmt.Sprintf方式写日志方法,其它级别雷同
流程分析:无
14. func (entry *Entry) Logln(level Level, format string, args ...interface{})
功能说明:不同级别日志以fmt.Sprintln并且没有新行的通用处理方法
流程分析:
1.如果当前待写的日志级别小于Logger的级别,才会调用entry.log
2.调用entry.sprintlnn方法,处理用户日志
15. func (entry *Entry) Traceln(args ...interface{})
功能说明:entry的TraceLevel级别写日志方法,其它级别雷同
流程分析:
15. func (entry *Entry) sprintlnn(args ...interface{}) string
功能说明:试图在每个参数之间加空格,并且去掉fmt.Sprintln多加的新行
流程分析:调用fmt.Sprintln处理用户日志,然后去掉多加的新行
2.logrus.Logger结构
2.1 类型
type Logger struct {
Out io.Writer // Logger默认输出位置,系统默认为os.Stderr,可以设置可以更灵活,如:Kafka
// 使用Logger.SetOutput()方法设置
Hooks LevelHooks // 挂载在Logger上Hook集合,二维数组结构,每个日志级别对应一个Hook数组切片
// 类型为 type LevelHooks map[Level][]Hook,使用Logger.AddHook()添加
Formatter Formatter // 所有日志在输出到Out上之前,都会经过formatter处理,默认为TextFormatter,
// 也可以设置为JSONFormatter,当输出为TTY设备,日志会用不同颜色显示,文件不行
// 使用Logger.SetFormatter()添加
ReportCaller bool // 日志是否记录调用者信息,默认关闭,可以使用Logger.SetReportCaller()设置
Level Level // 所有日志是否要经过默认的Out还是Hook,都有Level等级决定,默认为logrus.InfoLevel
// 那么只允许Info(), Warn(), Error() and Fatal()处理日志,使用Logger.SetLevel()设置
mu MutexWrap // 互斥锁包装,默认打开,可以使用Logger.SetNoLock关闭
entryPool sync.Pool // 存放临时的Entry对象,减少GC对Entry对象的内存回收,提高Entry对象复用,提高效率
ExitFunc exitFunc // 日志退出回调函数,默认为os.Exit
}
2.2 方法
1. func New() *Logger
- 功能说明:创建一个Logger对象
- 流程分析:无,见类型说明部分
2. func (logger *Logger) newEntry() *Entry
功能说明:创建一个Entry对象
流程分析:先尝试从entryPool中取一个Entry对象。若失败,调用NewEntry创建一个,并返回
3. func (logger *Logger) releaseEntry(entry *Entry)
功能说明:暂时回收Entry对象
流程分析:
1.entry.Data设置为空map,等待GC下一次运行回收
2.将entry放入entryPool中,等待GC下一次运行回收
4. WithField/WithFields/WithError/WithTime
功能说明:这4个方法都是往日志中添加字段,返回一个Entry对象
流程分析:
1.先创建一个Entry对象
2.然后分别调用Entry对象的方法,前3个方法是往Entry.Data中添加字段,WithTime是更新Entry写日志时间
3.通过defer释放创建的Entry对象
5. func (logger *Logger) Logf(level Level, format string, args ...interface{})
功能说明:以fmt.Sprintf格式写日志
流程分析:
1.若level <= logger.Level,才会处理日志
2.newEntry创建entry对象
3.entry.Logf()处理日志
4.releaseEntry回收entry对象
6. Tracef/Debugf/Infof/Printf/Warnf/Warningf/Errorf/Fatalf
功能说明:以fmt.Sprintf格式格式化用户日志,并写入对应级别的日志
流程分析:
7. func (logger *Logger) Log(level Level, args ...interface{})
功能说明:以fmt.Sprint格式写日志
流程分析:
1.若level <= logger.Level,才会处理日志
2.newEntry创建entry对象
3.entry.Log()处理日志
4.releaseEntry回收entry对象
8. Trace/Debug/Info/Print/Warn/Warning/Error/Fatal
功能说明:以fmt.Sprint格式格式化用户日志,并写入对应级别的日志
流程分析:
9. func (logger *Logger) Logln(level Level, args ...interface{})
功能说明:不同级别日志以fmt.Sprintln,并且没有新行的通用处理方法
流程分析:
1.若level <= logger.Level,才会处理日志
2.newEntry创建entry对象
3.entry.Log()处理日志
4.releaseEntry回收entry对象
10. Traceln/Debugln/Infoln/Println/Warnln/Warningln/Errorln/Fatalln
功能说明:以不同级别的方式使用Logln写入日志
流程分析:
3.logrus.Hook结构
1.1 类型
type Hook interface {
Levels() []Level // 当前Hook可有效用于哪些级别的日志
Fire(*Entry) error // 当前Hook处理方法,将被LevelHooks.Fire方法执行
}
type LevelHooks map[Level][]Hook // 每级日志对应一个Hook数组,有的写入本地磁盘,有的输送到日志服务器上,有的...
Hook是一个接口,每一个用户自定义的Hook,都必须实现Levels()方法和Fire()方法,
用户可以封装复杂的结构及方法,实现Hook接口,通过Fire()可以将特定格式的日志数据,记录到特定的目的地。
可参考:github.com/rifflock/lfshook、gopkg.in/sohlich/elogrus.v2、github.com/pkg/logrus_amqp
1.2 方法
1. func (hooks LevelHooks) Add(hook Hook)
功能说明:给不同级别日志Hook列表中添加Hook,这些级别由用户实现的Hook.Levels()方法决定
流程分析:以下是Add()方法代码
for _, level := range hook.Levels() {
hooks[level] = append(hooks[level], hook)
}
循环往Levels()对应的Level列表中,分别添加Hook
2. func (hooks LevelHooks) Fire(level Level, entry *Entry) error
功能说明:处理level级别下所有Hook
流程分析:以下是Fire()方法代码
for _, hook := range hooks[level] {
if err := hook.Fire(entry); err != nil {
return err
}
}
循环处理level对应的hooks列表中的hook,调用每个hook中用户实现的Fire方法,并传入当前logging的entry对象
* Hook方法集:
Levels() 决定当前Hook将作用于哪些级别的日志
Fire() 处理当前日志的用户自定义回调处理方法 * LevelHooks方法集:
Add(hook) 给不同级别日志Hook列表中添加hook,这些级别由hook.Levels()决定
Fire(level, entry) 处理level对应的hook列表中的所有hook,即调用它们各自的Fire()方法 * LevelHooks结构:
type LevelHooks map[Level][]Hook,图示如下: PanicLevel --> hook1 | hook2 | hook3 | hook4 | hook5
FatalLevel --> hook2 | hook3 | hook4 | hook5
ErrorLevel --> hook2 | hook3 | hook5
WarnLevel --> hook4 | hook5
InfoLevel --> hook3
DebugLevel --> hook2
TraceLevel --> hook2 | hook4
4.Entry与Logger的关系
Entry是每条日志记录的实体,每记录一条日志,都会创建一个Entry对象,里面包含具体日志记录的数据字段和方法集。包括:
Message(用户记录原始数据),Time(日志时间),Level(记录级别),Data(自定义格式字段),Caller(运行时调用者信息),
Buffer(经过Logger.Formatter处理后的序列化数据),err(日志记录出错记录),Logger(当前Entry所属的Logger)。Logger是一个全局日志工具,包含:
Out(默认日志记录的Writer),Hooks(Hook机制),Formatter(默认日志记录的格式化器),
ReportCaller(默认日志记录,记录运行时调用者信息的开关),Level(所有日志记录的过滤级别,包括所有添加的Hook),
mu(Logger操作互斥锁), entryPool(Entry对象缓冲池),ExitFunc(退出应用程序处理函数,默认为os.EXIT())。所有记录日志的上层操作接口是由Logger提供,Entry属于后台记录的实体,Logger每提交一条日志,都对应一个Entry对象,并最后交由它处理。
Logger可以高度定制,使用Hook钩子机制,可以做到多级别输出、格式化输出、多样化输出(不同输出目的地)。
logrus学习笔记的更多相关文章
- golang日志框架--logrus学习笔记
golang日志框架--logrus学习笔记 golang标准库的日志框架非常简单,仅仅提供了print,panic和fatal三个函数,对于更精细的日志级别.日志文件分割以及日志分发等方面并没有提供 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
随机推荐
- 【Ionic】---Using Local Notifications In Your Ionic Framework App
Using Local Notifications In Your Ionic Framework App 配置好ng-cordova先 <script src="lib/ngCord ...
- sqlserverToXML
--raw模式 以属性的形式展示select * from goods for xml rawselect *from goods for xml raw('goods') --修改节点名称selec ...
- mysql存储过程游标加计划任务事件调度器
存储过程加事件调度器 -- 存储过程 (多个)游标的使用 临时表的使用(让执行时间从一个小时降低到5分钟)DELIMITER $$ DROP PROCEDURE IF EXISTS `eval_cal ...
- 三、gridView增删改查
1. 新增或修改一条数据 1.1 添加 新增或修改按钮 <div style="width: 120px; float: right; padding-top: 3px"&g ...
- Spring课程 Spring入门篇 3-1 Spring bean装配(上)之bean的配置项及作用域
课程链接: 本节主要讲了四大块 1 bean的作用域 2 bean作用域代码演练 3 单例 多例应用场景 4 bean的配置项(不重要) 1 bean的作用域 1.1 singleton :单例 1. ...
- 基于vue-cli 将webpack3 升级到 webpack4 配置
升级webpack4前 先删除之前的webpack, babel-loader 下载 webpack npm i -D webpack@4 webpack-cli@3 webpack-dev- ...
- python面试题——框架和其他(132题)
一.框架对比 (1)django.flask.tornado框架的比较? Django:简单的说Django是一个大而全的Web框架,内置了很多组件,ORM.admin.Form. ModelForm ...
- android 扇形菜单
引言: android中的菜单与windows的菜单没有什么区别,基本就是一个矩形框,如下: 这个菜单有多么能经得住历史的考验我就不多说了!我们再来看看最新有关手机可操作区域的调查 有此可以看出屏幕越 ...
- Android 5.0 以上监听网络变化
大家好,大概有一个多月没有更新博客了,我是干什么去了呢?很明显,程序员当然要加班……这一次跟大家分享一下新项目的一些心得. 监听网络变化在开发中是经常用到的,例如我们断网有一些友好的提示,或者根据不同 ...
- html和java的交互,利用jsBridge开源框架
html中,js注册监听和回调 function connectWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBrid ...