package f5 import ( "q5" "os" "sync" "fmt" "time" ) type tgLogMsgNode struct { gameId int32 jsonStr string next *tgLogMsgNode } type tgLog struct { isPolyLog bool topNode *tgLogMsgNode botNode *tgLogMsgNode msgMutex sync.Mutex chGoSaveExit chan int } func (this *tgLog) init() { this.chGoSaveExit = make(chan int) go this.goSaveToFile() } func (this *tgLog) unInit() { this.chGoSaveExit <- 1 } func (this *tgLog) SetPolyLog(isPolyLog bool) { this.isPolyLog = isPolyLog } func (this *tgLog) AddTrackLog( gameId int32, accountId string, remoteAddr string, logClass1 int32, logClass2 int32, prop map[string]string) { eventName := fmt.Sprintf("event_%d_%d", logClass1, logClass2) this.AddTrackLogEx(gameId, accountId, remoteAddr, eventName, prop) } func (this *tgLog) AddTrackLogEx( gameId int32, accountId string, remoteAddr string, eventName string, prop map[string]string) { logObj := struct { AccountId string `json:"#account_id"` Type string `json:"#type""` Time string `json:"#time"` EventName string `json:"#event_name""` Ip string `json:"#ip""` Properties map[string]string `json:"properties"` } { AccountId: accountId, Type: "track", Time: time.Now().Format("2006-01-02 15:04:05"), EventName: eventName, Ip: remoteAddr, Properties: prop, } p := new(tgLogMsgNode) p.gameId = gameId p.jsonStr = q5.EncodeJson(logObj) this.msgMutex.Lock() defer this.msgMutex.Unlock() if this.botNode != nil { this.botNode.next = p this.botNode = p } else { this.topNode = p this.botNode = p } } func (this *tgLog) goSaveToFile() { var workNode *tgLogMsgNode for { select { case <-this.chGoSaveExit: return case <-time.After(time.Millisecond * 1000 * 10): } this.msgMutex.Lock() workNode = this.topNode this.topNode = nil this.botNode = nil this.msgMutex.Unlock() if workNode != nil { for workNode != nil { f := this.getLogFile(workNode.gameId) if f != nil { f.Write([]byte(workNode.jsonStr + "\n")) f.Close() } workNode = workNode.next } } } } func (this *tgLog) getLogFile(gameId int32) *os.File { fileName := fmt.Sprintf(TGLOG_FILENAME, os.Getpid(), time.Now().Format("20060102")) logDir := "" if this.isPolyLog { logDir = fmt.Sprintf(POLY_TGLOG_ROOT, _app.GetPkgName(), gameId) } else { logDir = fmt.Sprintf(TGLOG_ROOT, _app.GetPkgName()) } q5.ForceCreateDir(logDir) if f, err := os.OpenFile(logDir + fileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err == nil { return f } else { _sysLog.Warning("tgLog.goSaveToFile err:%s", err) return nil } }