上一篇中我們已經把日誌寫入檔案中了,但是還有一些問題,可以看到我們日誌內容沒有記錄時間,也沒有日誌級別。錯誤日誌,沒有錯誤的檔案和行號,也不知道在哪個函式出錯的,這些我們也是需要加入進去的。
所以,我們的日誌列印的內容應該是這樣的:
2018-11-08 18:18:18.888 DEBUG [logDebug.go/logDebug.Debug:20] this is a debug log
複製程式碼
我們現在file.go
的Debug方法中將時間加入進去:
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
中新增一個方法:
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方法:
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方法相同的程式碼即可。但是這樣太麻煩了,我們提取一個公共函式來回省點我們很多時間。
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日誌庫也實現了。