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 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学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 怎么通过QQ账号登录记录精确查找登录过的
- 下一篇: 龟多少钱一斤啊?
