• 世卫将“游戏障碍”列为新疾病 哪些症状可被确诊? 2019-05-07
  • 多部门三令五申禁网售彩票,世界杯竞猜APP上仍热卖 2019-05-07
  • 退牧还草 为藏羚羊迁徙让路 2019-05-05
  • 候选企业:苏宁控股集团有限公司 2019-05-05
  • 这是全国精气最为集中的地方 被称为中国丹田所在 ——凤凰网房产 2019-05-04
  • 状态差被郎平退货?丁霞归队仍是国内最好二传 2019-05-01
  • 天津市环境保护突出问题边督边改公开信息 2019-05-01
  • 董明珠代表:建立保护企业人才机制 遏制“恶意挖人”现象 2019-04-30
  • 7月1日起铁路将实施新列车运行图 北京再增12.5对复兴号 2019-04-24
  • 国际国内--山西频道--人民网 2019-04-23
  • 奥迪在华“三十已立” 坐拥天时,指向人和 2019-04-23
  • 中考期间 太原27个公共自行车服务点有人值守 2019-04-10
  • 有人被逼作弊,有人收获爱情,和高考有关的60个瞬间 2019-04-10
  • 深圳2018年将开行3趟援疆旅游扶贫专列 2019-04-05
  • 警惕套路贷 放贷是幌子 建议增设非法放贷罪 2019-03-25
  • 山东十一选五专家杀号 Chinaunix首页 | 论坛 | 山东十一选五专家杀号
    • 博客访问: 139607
    • 博文数量: 94
    • 博客积分: 0
    • 博客等级: 民兵
    • 技术积分: 640
    • 用 户 组: 普通用户
    • 注册时间: 2015-09-30 08:58
    个人简介

    x

    文章分类

    全部博文(94)

    文章存档

    2019年(4)

    2018年(10)

    2017年(26)

    2016年(38)

    2015年(16)

    我的朋友

    分类: LINUX

    2019-03-04 14:19:26

    logrus学习笔记

    1.logrus.Entry结构

    1.1 类型

     山东十一选五专家杀号 www.pqwa.net 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结构:
        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
        
        * LevelHooks方法集:
        Add(hook)           给不同级别日志Hook列表中添加hook,这些级别由hook.Levels()决定
        Fire(level, entry)  处理level对应的hook列表中的所有hook,即调用它们各自的Fire()方法    

    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钩子机制,可以做到多级别输出、格式化输出、多样化输出(不同输出目的地)。

    阅读(3871) | 评论(0) | 转发(0) |
    0

    上一篇:Python学习之装饰器@用法

    下一篇:没有了

    给主人留下些什么吧!~~
    评论热议
    请登录后评论。

    登录 注册

  • 世卫将“游戏障碍”列为新疾病 哪些症状可被确诊? 2019-05-07
  • 多部门三令五申禁网售彩票,世界杯竞猜APP上仍热卖 2019-05-07
  • 退牧还草 为藏羚羊迁徙让路 2019-05-05
  • 候选企业:苏宁控股集团有限公司 2019-05-05
  • 这是全国精气最为集中的地方 被称为中国丹田所在 ——凤凰网房产 2019-05-04
  • 状态差被郎平退货?丁霞归队仍是国内最好二传 2019-05-01
  • 天津市环境保护突出问题边督边改公开信息 2019-05-01
  • 董明珠代表:建立保护企业人才机制 遏制“恶意挖人”现象 2019-04-30
  • 7月1日起铁路将实施新列车运行图 北京再增12.5对复兴号 2019-04-24
  • 国际国内--山西频道--人民网 2019-04-23
  • 奥迪在华“三十已立” 坐拥天时,指向人和 2019-04-23
  • 中考期间 太原27个公共自行车服务点有人值守 2019-04-10
  • 有人被逼作弊,有人收获爱情,和高考有关的60个瞬间 2019-04-10
  • 深圳2018年将开行3趟援疆旅游扶贫专列 2019-04-05
  • 警惕套路贷 放贷是幌子 建议增设非法放贷罪 2019-03-25
  • 达州福利彩票中心在哪 福利彩票开奖结果 任选9场奖金规则 pk10计划人工在线计划 南国特区七星彩票论坛 福彩3d和值走势图 pk10杀号方法 上海时时彩乐乐 体彩p3开机号试机号近100期 画彩票走势图 北京赛车杀号公式 足彩进球彩165期 群英会开奖直播视频 双色球开 欢乐麻将 左岸春风一语断蓝