上一篇中已經講述了日誌庫的需求,這一篇中咱們來實現日誌庫的原型。單元測試
新建一個項目,這裏我用的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
:ui
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
,咱們須要一些常量。this
package hm_log
const (
DebugLevel = iota
TraceLevel
InfoLevel
WarnLevel
ErrorLevel
FatalLevel
)
複製代碼
由於咱們是寫入文件中的,因此須要進行打開文件操做。爲了在後續的日誌查看方便,咱們須要將普通日誌和錯誤日誌分開存儲。spa
type FileLog struct {
logPath string
logName string
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
來測試咱們寫的文件日誌庫。code
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文件。打開文件,能夠看到咱們的日誌已經成功寫入了日誌文件裏面。下一篇咱們完善這個文件日誌庫原型。orm