Golang日志與配置文件的設計與實踐
意義
- 在項目開始之前,先根據大概業務設計日志系統。
- 一個好的日志系統在項目維護時非常重要。 </ol>
- 時間戳
- 日志調用地點:文件+行號
- 報錯級別 致命 錯誤 警告 信息 調試
- Summary
- 關鍵內存Dump </ol>
我的日志系統中的內容:
這些信息方便排查故障。
配置文件:
直接使用yaml
包: gopkg.in/yaml.v2
配置文件越簡單越好。不然容易出錯
代碼
package Loggerimport ( "encoding/json" "os" "runtime" "strconv" "time" ) import "caidanhezi-go/utility"
var outFile *os.File
// Logone 單條Log的結構 type Logone struct { Timestamp int64 Codeline string Level int // 出錯級別: 0致命 1錯誤 2警告 3信息 4調試 Info string Detail map[string]interface{} }
// init 只負責打開文件 func init() { outFile, _ = os.OpenFile(utility.Conf.LogFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) }
// Write 寫入Log func Write(Level int, Info string, Detail map[string]interface{}) { var newLog Logone newLog.Timestamp = time.Now().Unix() , file, line, := runtime.Caller(1) newLog.Codeline = file + " " + string(strconv.Itoa(line)) newLog.Level = Level newLog.Detail = Detail newLog.Info = Info outFile.Write(func() []byte { b, _ := json.Marshal(newLog) b = append(b, '\n') return b }()) }
// CloseLogFile function: close logger file func CloseLogFile() { outFile.Close() }</pre>
runtime.Caller 可以返回調用日志的堆棧位置。其他沒什么特別的了。
為啥不直接用系統中的log?
因為默認log缺少緩存。
緩存系統可以讓系統具有日志激增的緩沖措施。日志監控方案
包: “github.com/ActiveState/tail”
var err error t, _ := tail.TailFile(utility.Conf.LogFile, //日志文件位置 tail.Config{Follow: true, Location: &tail.SeekInfo{0, 2}}) for line := range t.Lines { //每次寫入日志都會進入這個循環 for index := 0; index < len(connected); index++ { if err = websocket.Message.Send(&connected[index], line.Text); err != nil { //對每個連接監控單元都發送日志數據 fmt.Println("Can't send")//掉線的監控T掉。 // index2 := index + 1 connected = append([]websocket.Conn{}, connected[:index]...) if len(connected) >= index+1 { connected = append(connected, connected[index+1:]...) } continue } } }
注意:SeekInfo 這里的API說明在這里https://golang.org/pkg/os/#File.Seek
我這里是從最尾部開始。(之前文件的內容都忽略了)
來自:http://www.philo.top/2015/07/06/golangLog/