Golang - 日誌庫實戰


目錄結構


| - myLog
	| - mylog.go
	| - file_log.go
| - 項目目錄
	| - main.go 
	

日誌庫文件

  • mylog.go
package mylog

import (
	"path"
	"runtime"
)

// 需求:
// 	1. 在終端打印
// 	2. 同時記錄到文件中
//	3. 日誌分級別: debug trace info warning err critical

const (
	// DEBUG 級別0, 調試
	DEBUG = iota
	// TRACE 級別1, 路由追蹤
	TRACE
	// INFO 級別2, 信息
	INFO
	// WARNING 級別3, 警告
	WARNING
	// ERROR 級別4, 錯誤
	ERROR
	// CRITICAL 級別5, 崩潰
	CRITICAL
)

// 返回值爲文件名, 函數名, 行號
func getCallerInfo() (fileName, funcName string, line int) {
	pc, fileName, line, ok := runtime.Caller(3) // 這個2表示往上調幾級, fileName此時爲全路徑

	if !ok {
		return
	}

	fileName = path.Base(fileName)                     // path.Base()處理成分隔符最後一段,並返回
	funcName = path.Base(runtime.FuncForPC(pc).Name()) // 根據指針找到函數, 再處理函數路徑
	return fileName, funcName, line
}

  • file_log.go
package mylog

import (
	"fmt"
	"os"
	"time"
)

// FileLogger 往文件中記錄日誌的結構體
type FileLogger struct {
	level       int
	logFilePath string
	logFileName string
	logFile     *os.File
}

// NewFileLogger FileLogger的構造函數
func NewFileLogger(level int, logFilePath, logFileName string) *FileLogger {
	flObj := &FileLogger{
		level:       level,
		logFilePath: logFilePath,
		logFileName: logFileName,
	}
	flObj.initFileLogger() // 調用下邊的文件初始化方法
	return flObj
}

// fileLogger的初始化方法
func (f *FileLogger) initFileLogger() {
	// 文件路徑
	fPath := fmt.Sprintf("%s%s", f.logFilePath, f.logFileName)
	file, err := os.OpenFile(fPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)

	if err != nil {
		panic(fmt.Sprintf("open file %v failed\n", fPath))
	}

	// 把句柄賦值給結構體的logFile字段
	f.logFile = file
}

// 處理日誌
func (f *FileLogger) logHandle(msg, loglevel string, args ...interface{}) {
	fileName, funcName, line := getCallerInfo()

	// [2019-04-01 19:39:21] [DEBUG] main.go [line 14] id爲10的用戶一直在嘗試登錄
	nowStr := time.Now().Format("[2006-01-02 15:04:05.000]")
	logMsg := fmt.Sprintf("%s [%s] [%s:%s %d] %s\n", nowStr, loglevel, fileName, funcName, line, msg)
	logMsg = fmt.Sprintf(logMsg, args...)

	fmt.Println(logMsg)
	f.logFile.WriteString(logMsg)
}

// DEBUG 記錄日誌
func (f *FileLogger) DEBUG(msg string, args ...interface{}) {
	// 如果設置的級別超過DEBUG, 就不寫日誌
	if f.level > DEBUG {
		return
	}
	f.logHandle(msg, "DEBUG", args...)
}

// TRACE 記錄日誌
func (f *FileLogger) TRACE(msg string, args ...interface{}) {
	if f.level > TRACE {
		return
	}
	f.logHandle(msg, "TRACE", args...)
}

// INFO 記錄日誌
func (f *FileLogger) INFO(msg string, args ...interface{}) {
	if f.level > INFO {
		return
	}
	f.logHandle(msg, "INFO", args...)
}

// WARNING 記錄日誌
func (f *FileLogger) WARNING(msg string, args ...interface{}) {
	if f.level > WARNING {
		return
	}
	f.logHandle(msg, "WARNING", args...)
}

// ERROR 記錄日誌
func (f *FileLogger) ERROR(msg string, args ...interface{}) {
	if f.level > ERROR {
		return
	}
	f.logHandle(msg, "ERROR", args...)
}

// CRITICAL 記錄日誌
func (f *FileLogger) CRITICAL(msg string, args ...interface{}) {
	if f.level > CRITICAL {
		return
	}
	f.logHandle(msg, "CRITICAL", args...)
}


調用文件

package main

// 寫了一個項目, 想要在代碼中記錄日誌
import mylog "code.oldboy.com/day04/14myLog"

const (
	// LogLevel 設置記錄log的級別
	LogLevel = mylog.DEBUG

	// LogPath 設置日誌路徑
	LogPath = "./"

	// LogName 設置日誌文件名
	LogName = "xx.log"
)

func main() {
	// 實例化一個fileLog的結構體
	fl := mylog.NewFileLogger(LogLevel, LogPath, LogName)

	fl.DEBUG("代碼已經執行")
	fl.INFO("id11用戶登錄")
	fl.CRITICAL("程序報錯, 錯誤碼爲%d", 131231)
	fl.ERROR("id爲10的用戶一直在嘗試登錄")
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章