go 開發屬於自己的日誌庫-檔案日誌庫原型實現
上一篇中已經講述了日誌庫的需求,這一篇中我們來實現日誌庫的原型。
新建一個專案,這裡我用的hm_log
,在專案下新建一個log_interface.go
日誌規範,定義日誌級別的方法:
package hm_log type Log interface { Debug(format string, args ...interface{}) // ...表示接收可變引數 Trace(format string, args ...interface{}) Info(format string, args ...interface{}) Warn(format string, args ...interface{}) Error(format string, args ...interface{}) Fatal(format string, args ...interface{}) Close() // 檔案需要進行關閉操作 } 複製程式碼
因為我們是要列印到檔案裡面去,所以我還需要新建一個file.go
:
package hm_log type FileLog struct { logPath string logName string } func NewFileLog(logPath, logName string) Log { // 為什麼返回的Log,上一篇中已經說明 return &FileLog{ logPath: logPath, logName: logName, } } func (f *FileLog) Debug(format string, args ...interface{}) { } func (f *FileLog) Trace(format string, args ...interface{}) { } func (f *FileLog) Info(format string, args ...interface{}) { } func (f *FileLog) Warn(format string, args ...interface{}) { } func (f *FileLog) Error(format string, args ...interface{}) { } func (f *FileLog) Fatal(format string, args ...interface{}) { } func (f *FileLog) Close() { } 複製程式碼
現在我們基本實現了file的初始程式碼了,然後現在來實現file的功能。實現功能之前,新建一個log_const.go
,我們需要一些常量。
package hm_log const ( DebugLevel = iota TraceLevel InfoLevel WarnLevel ErrorLevel FatalLevel ) 複製程式碼
因為我們是寫入檔案中的,所以需要進行開啟檔案操作。為了在後續的日誌檢視方便,我們需要將普通日誌和錯誤日誌分開儲存。
type FileLog struct { logPathstring logNamestring file*os.File warnFile *os.File } func NewFileLog(logPath, logName string) Log { // 為什麼返回的Log,上一篇中已經說明 log := &FileLog{ logPath: logPath, logName: logName, } log.init() return log } func (f *FileLog) init() { // 一般日誌 filename := fmt.Sprintf("%s/%s.log", f.logPath, f.logName) file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755) // os.O_CREATE 建立檔案 os.O_APPEND 追加寫入 os.O_WRONLY 只寫操作 if err != nil { panic(fmt.Sprintf("open faile %s failed, err: %v", filename, err) } f.file = file // 錯誤日誌 warnfilename := fmt.Sprintf("%s/%s.log.wf", f.logPath, f.logName) warnfile, err := os.OpenFile(warnfilename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755) // os.O_CREATE 建立檔案 os.O_APPEND 追加寫入 os.O_WRONLY 只寫操作 if err != nil { panic(fmt.Sprintf("open faile %s failed, err: %v", warnfilename, err) } f.warnFile = warnfile } 複製程式碼
然後就可以實現之前的日誌方法了。
func (f *FileLog) Debug(format string, args ...interface{}) { fmt.Fprintf(f.file, format, args...) fmt.Fprintln(f.file) } func (f *FileLog) Trace(format string, args ...interface{}) { fmt.Fprintf(f.file, format, args...) fmt.Fprintln(f.file) } func (f *FileLog) Info(format string, args ...interface{}) { fmt.Fprintf(f.file, format, args...) fmt.Fprintln(f.file) } func (f *FileLog) Warn(format string, args ...interface{}) { fmt.Fprintf(f.warnFile, format, args...) fmt.Fprintln(f.warnFile) } func (f *FileLog) Error(format string, args ...interface{}) { fmt.Fprintf(f.warnFile, format, args...) fmt.Fprintln(f.warnFile) } func (f *FileLog) Fatal(format string, args ...interface{}) { fmt.Fprintf(f.warnFile, format, args...) fmt.Fprintln(f.warnFile) } func (f *FileLog) Close() { f.file.Close() f.warnFile.Close() } 複製程式碼
到這裡檔案日誌庫基本完成了,當寫完一個功能時,我們需要進行單元測試,所以我們新建一個log_test.go
來測試我們寫的檔案日誌庫。
package log import ( "testing" ) func TestFileLog(t *testing.T) { log := NewFileLog(".", "test") log.Debug("this is file debub test") log.Warn("this is file warn test") log.Close() } 複製程式碼
使用go test進行單元測試。然後可以看到我們的專案下多了一個test.log和test.log.wf檔案。開啟檔案,可以看到我們的日誌已經成功寫入了日誌檔案裡面。下一篇我們完善這個檔案日誌庫原型。