Golang日志与配置文件的设计与实践
jopen
9年前
意义
- 在项目开始之前,先根据大概业务设计日志系统。
- 一个好的日志系统在项目维护时非常重要。
我的日志系统中的内容:
- 时间戳
- 日志调用地点:文件+行号
- 报错级别 致命 错误 警告 信息 调试
- Summary
- 关键内存Dump
这些信息方便排查故障。
配置文件:
直接使用yaml
包: gopkg.in/yaml.v2
配置文件越简单越好。不然容易出错
代码
package Logger import ( "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() }
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/