GoLang實(shí)現(xiàn)日志收集器流程講解
Go自己動(dòng)手實(shí)現(xiàn)日志收集
看日志是開發(fā)者平時(shí)排查BUG所必須的掌握的技能,但是日志是如何來的呢?通過平時(shí)開發(fā)者自己打日志,經(jīng)過日志包進(jìn)行處理,打印日志到控制臺(tái)還是記錄日志到文件中!
下面咱就來學(xué)一下日志是如何記錄下來的
1. 日志器的接口
? 以下日志器定義了各類日志器的行為,通過RegisterWriter
注冊(cè)實(shí)現(xiàn)了日志器的子類日志器,然后通過Log
方法來進(jìn)行循環(huán)調(diào)用注冊(cè)進(jìn)來的日志收集器的write
寫日志方法。
// 聲明日志寫入器接口 type LogWriter interface { Write(data interface{}) error } // 日志器 type Logger struct { // 這個(gè)日志器用到的日志寫入器 writerList []LogWriter } // 注冊(cè)一個(gè)日志寫入器 func (l *Logger) RegisterWriter(writer LogWriter) { l.writerList = append(l.writerList, writer) } // 將一個(gè)data類型的數(shù)據(jù)寫入日志 func (l *Logger) Log(data interface{}) { // 遍歷所有注冊(cè)的寫入器 for _, writer := range l.writerList { // 將日志輸出到每一個(gè)寫入器中 writer.Write(data) } } // 創(chuàng)建日志器的實(shí)例 func NewLogger() *Logger { return &Logger{} }
2. 命令寫入日志器
? 這個(gè)日志器實(shí)現(xiàn)了日志器的接口行為write
,可以進(jìn)行日志的寫入,其寫入手法是通過Os
包來寫入到命令行(控制臺(tái))中!
// 命令行寫入器 type consoleWriter struct { } // 實(shí)現(xiàn)LogWriter的Write()方法 func (f *consoleWriter) Write(data interface{}) error { // 將數(shù)據(jù)序列化為字符串 str := fmt.Sprintf("%v\n", data) // 將數(shù)據(jù)以字節(jié)數(shù)組寫入命令行中 _, err := os.Stdout.Write([]byte(str)) return err } // 創(chuàng)建命令行寫入器實(shí)例 func NewConsoleWriter() *consoleWriter { return &consoleWriter{} }
3. 文件寫入日志器
這也是實(shí)現(xiàn)了日志器的一個(gè)實(shí)現(xiàn)類,文件日志器,一種常見的將日志寫入文件記錄的日志收集器。使用前需要先SetFile
設(shè)置好日志文件名,最后將日志作為字節(jié)寫入到文件中。
// 聲明文件寫入器 type fileWriter struct { file *os.File } // 設(shè)置文件寫入器寫入的文件名 func (f *fileWriter) SetFile(filename string) (err error) { // 如果文件已經(jīng)打開, 關(guān)閉前一個(gè)文件 if f.file != nil { f.file.Close() } // 創(chuàng)建一個(gè)文件并保存文件句柄 f.file, err = os.Create(filename) // 如果創(chuàng)建的過程出現(xiàn)錯(cuò)誤, 則返回錯(cuò)誤 return err } // 實(shí)現(xiàn)LogWriter的Write()方法 func (f *fileWriter) Write(data interface{}) error { // 日志文件可能沒有創(chuàng)建成功 if f.file == nil { // 日志文件沒有準(zhǔn)備好 return errors.New("file not created") } // 將數(shù)據(jù)序列化為字符串 str := fmt.Sprintf("%v\n", data) // 將數(shù)據(jù)以字節(jié)數(shù)組寫入文件中 _, err := f.file.Write([]byte(str)) return err } // 創(chuàng)建文件寫入器實(shí)例 func NewFileWriter() *fileWriter { return &fileWriter{} }
4. Demo演示
通過New的方式創(chuàng)建日志器,進(jìn)行注冊(cè)到日志器集合中,下面演示了兩種日志器如何使用?。?!
// 創(chuàng)建日志器 func createLogger() *Logger { // 創(chuàng)建日志器 l := NewLogger() // 創(chuàng)建命令行寫入器 cw := cmdwriter.NewConsoleWriter() // 注冊(cè)命令行寫入器到日志器中,cw實(shí)現(xiàn)了LogWriter接口,故可作為RegisterWriter函數(shù)的參數(shù),類型為L(zhǎng)ogwriter l.RegisterWriter(cw) // 創(chuàng)建文件寫入器 fw := filerwriter.NewFileWriter() // 設(shè)置文件名 if err := fw.SetFile("log.log"); err != nil { fmt.Println(err) } // 注冊(cè)文件寫入器到日志器中,fw實(shí)現(xiàn)了LogWriter接口 l.RegisterWriter(fw) return l } func main() { // 準(zhǔn)備日志器 l := createLogger() // 寫一個(gè)日志 l.Log("hello") }
5. 總結(jié)和提高
一個(gè)好的日志器功能是可擴(kuò)展的,上述例子僅只是可以擴(kuò)展不同種類的日志收集器。
在官方的logger中是可以進(jìn)行選擇寫入級(jí)別的,可以定義一個(gè)枚舉,在對(duì)應(yīng)的枚舉寫入級(jí)別下,進(jìn)行對(duì)應(yīng)的權(quán)限寫入,可以改造write方法,而不只是簡(jiǎn)單的寫入就完事了。
到此這篇關(guān)于GoLang實(shí)現(xiàn)日志收集器流程講解的文章就介紹到這了,更多相關(guān)Go日志收集內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang的時(shí)區(qū)和神奇的time.Parse的使用方法
這篇文章主要介紹了golang的時(shí)區(qū)和神奇的time.Parse的使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Golang中使用Date進(jìn)行日期格式化(沿用Java風(fēng)格)
這篇文章主要介紹了Golang中使用Date進(jìn)行日期格式化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04Go語言Web編程實(shí)現(xiàn)Get和Post請(qǐng)求發(fā)送與解析的方法詳解
這篇文章主要介紹了Go語言Web編程實(shí)現(xiàn)Get和Post請(qǐng)求發(fā)送與解析的方法,結(jié)合實(shí)例形式分析了Go語言客戶端、服務(wù)器端結(jié)合實(shí)現(xiàn)web數(shù)據(jù)get、post發(fā)送與接收數(shù)據(jù)的相關(guān)操作技巧,需要的朋友可以參考下2017-06-06