go開發屬於本身的日誌庫-文件日誌庫實現

上一篇中咱們已經把日誌寫入文件中了,可是還有一些問題,能夠看到咱們日誌內容沒有記錄時間,也沒有日誌級別。錯誤日誌,沒有錯誤的文件和行號,也不知道在哪一個函數出錯的,這些咱們也是須要加入進去的。函數

因此,咱們的日誌打印的內容應該是這樣的:this

2018-11-08 18:18:18.888 DEBUG [logDebug.go/logDebug.Debug:20]  this is a debug log
複製代碼

咱們如今file.go的Debug方法中將時間加入進去:spa

func (f *FileLog) Debug(format string, args ...interface{}) {
    now := time.Now()
    nowStr := now.Format("2006-01-02 15:04:05.999")// 這個數字格式是固定的不能改變的,可是-和:能夠更換
    

    fmt.Fprintf(f.file, nowStr)
    fmt.Fprintf(f.file, format, args...)
    fmt.Fprintln(f.file)
}
複製代碼

而後咱們再講日誌級別加進去,咱們以前定義了日誌級別常量,可是由於使用的iota,因此使用常量的時候,常量的值都是012,這種基本是沒人看的懂的,因此咱們須要將日誌級別已字符串的形式打印。咱們在log_const.go中新增一個方法:debug

func LogLevelString(level int) (levelStr string) {
	switch level {
	case DebugLevel:
		levelStr = "DEBUG"
	case TraceLevel:
		levelStr = "TRACE"
	case InfoLevel:
		levelStr = "INFO"
	case WarnLevel:
		levelStr = "WARN"
	case ErrorLevel:
		levelStr = "ERROR"
	case FatalLevel:
		levelStr = "FATAL"
	}
	return
}
複製代碼

能夠看到咱們制定制定的日誌格式裏面還有一個行號,文件名,因此咱們還須要獲取錯誤日誌所在的行號的文件名,新建util.go日誌

package hm_log

import(
    "runtime"
)

func GetLineInfo() (fileName, funcName string, lineNo int) {
   //pc 計數器, file 文件名, line 行號, ok 是否
   // runtime.Caller(4)這裏的4是一個層級關係,能夠嘗試使用0 1 2 3來看看
   // 4 在其餘項目中使用的時候,若是在log的test中,使用3
	pc, file, line, ok := runtime.Caller(4)
	if ok {
		fileName = file
		funcName = runtime.FuncForPC(pc).Name() // 獲取當前的方法
		lineNo = line
	}
	return
}
複製代碼

繼續完善Debug方法:code

func (f *FileLog) Debug(format string, args ...interface{}) {
    now := time.Now()
    nowStr := now.Format("2006-01-02 15:04:05.999")
    // 這個數字格式是固定的不能改變的,可是-和:能夠更換
    levelStr := LogLevelString(DebugLevel)
    fileName, funcName, lineNo := GetLineInfo()
    //因爲這裏返回的是全路徑的,可是咱們不須要,因此咱們只須要文件名以及相關的便可
    fileName = path.Base(fileName)
    funcName = path.Base(funcName)
    msg := fmt.Sprintf(format, args...)
    fmt.Fprintf(f.file, "%s %s [%s/%s:%d] %s\n", nowStr, levelStr, fileName, funcName, lineNo, msg)
}
複製代碼

而後再執行go.test,查看咱們的日誌文件,能夠看到日誌內容和以前定義的格式相同了。而後就其餘方法修改成Debug方法相同的代碼便可。可是這樣太麻煩了,咱們提取一個公共函數來回省點咱們不少時間。orm

func (f *FileLog) writeLog(file *os.File, level int, format string, args... interface{} {
    now := time.Now()
    nowStr := now.Format("2006-01-02 15:04:05.999")
    // 這個數字格式是固定的不能改變的,可是-和:能夠更換
    levelStr := LogLevelString(level)
    fileName, funcName, lineNo := GetLineInfo()
    //因爲這裏返回的是全路徑的,可是咱們不須要,因此咱們只須要文件名以及相關的便可
    fileName = path.Base(fileName)
    funcName = path.Base(funcName)
    msg := fmt.Sprintf(format, args...)
    fmt.Fprintf(file, "%s %s [%s/%s:%d] %s\n", nowStr, levelStr, fileName, funcName, lineNo, msg)
}

func (f *FileLog) Debug(format string, args ...interface{}) {
    f.writeLog(f.file, DebugLevel, format, args...)
}

...

func (f *FileLog) Warn(format string, args ...interface{}) {
    f.writeLog(f.warnFile, WarnLevel, format, args...)
}

...

複製代碼

基本上這個文件日誌庫就寫的差很少了,也基本實現了文件日誌庫的功能。下一篇咱們繼續將console日誌庫也實現了。字符串

相關文章
相關標籤/搜索