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 PanicCaller *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是一个接口,类型定义如下:
    go 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()方法代码
    go 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()方法代码
    go 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钩子机制,可以做到多级别输出、格式化输出、多样化输出(不同输出目的地)。

转载于:https://www.cnblogs.com/wayne666/p/10531535.html

logrus学习笔记相关推荐

  1. golang学习笔记(基础篇)

    LCY~~Golang学习笔记 一.Go语言开发环境 ##安装Go开发包以及VsCode Go开发包与vscode配置安装教程网址:https://www.liwenzhou.com/posts/Go ...

  2. Colly 学习笔记(二)——爬虫框架,抓取下载数据(上证A股数据下载)

    Colly 学习笔记(二)--爬虫框架,抓取下载数据(上证A股数据下载) Colly 学习笔记(一)--爬虫框架,抓取中金公司行业市盈率数据 Colly 学习笔记(二)--爬虫框架,抓取下载数据(上证 ...

  3. go-pitaya学习笔记(6)-cluster-protobuf demo分析

    学习笔记: 我家别墅靠大海/pitaya-learn 尝试集成功能:我家别墅靠大海/pitaya-game 如果你正在看此笔记,请你左边放笔记,右边放chatdemo的代码!! 我是按代码的顺序记的笔 ...

  4. go-pitaya学习笔记(10)-worker demo分析

    学习笔记: 我家别墅靠大海/pitaya-learn 尝试集成功能:我家别墅靠大海/pitaya-game 如果你正在看此笔记,请你左边放笔记,右边放chatdemo的代码!! 我是按代码的顺序记的笔 ...

  5. go-pitaya学习笔记(3)-小小的测试

    学习笔记: 我家别墅靠大海/pitaya-learn 尝试集成功能:我家别墅靠大海/pitaya-game 如果你正在看此笔记,请你左边放笔记,右边放chatdemo的代码!! 我是按代码的顺序记的笔 ...

  6. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  7. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  8. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  9. 2020年Yann Lecun深度学习笔记(下)

    2020年Yann Lecun深度学习笔记(下)

最新文章

  1. R将dataframe数据保存为csv文件
  2. 你真的会二分查找吗?
  3. Dijkstra算法的思想和数学归纳法
  4. Spring 梳理 - @Component
  5. 《机器学习》 周志华学习笔记第二章 模型评估与选择(课后习题)
  6. multism中ui和uo应该怎么表示_欧阳娜娜上节目痛哭,坦言压力太大睡不着,明星都怎么了?...
  7. 升级Tornado到4后weibo oauth登录不了
  8. 删除virtual bridge
  9. 如何导出久其报表所有数据_久其报表不能传输怎么办?
  10. 人人商城删除后台菜单“小程序”
  11. folder汇总字段的实现
  12. python预测身高 青少年编程电子学会python编程等级考试一级真题解析2021-12
  13. 基于单幅图像Patch Map的稳健除雾(PMS-Net: Robust Haze Removal Based on Patch Map for Single Images_CVPR_2019)
  14. python的label属性_python内置GUI库tkinter——Label类属性
  15. 借鉴美团文章实现的动态线程池,已开源
  16. FL STUDIO宿主软件v20.9中文版使用技巧心得
  17. 让旧衣服换新颜 听听章泽天怎么说!
  18. 2021年甘肃省高考成绩一分一段表查询,2021年甘肃高考成绩排名查询系统,甘肃高考位次排名查询...
  19. Flutter开发桌面应用
  20. 一文详解计算机网络经典面试题

热门文章

  1. python实现二叉树的重建1 之由前序遍历和中序遍历重建
  2. 5 用python进行OpenCV实战之图像变换2(旋转)
  3. 亲手建造自己想要的生活
  4. photoshop小结
  5. TENSORFLOW变量作用域(VARIABLE SCOPE)
  6. SpringBoot整合MyBatis详细教程~
  7. 编译器设计-有限自动机
  8. 无人驾驶传感器融合技术
  9. 视觉SLAM技术应用
  10. 2021年大数据ELK(十七):Elasticsearch SQL 订单统计分析案例