// Close disables the DirectLog instance, flushes any remaining entries to disk, and // then closes the backing log file. func (this *DirectLog) Close() { this.lock.Lock() defer this.lock.Unlock() this.enabled = false this.print(xlog.NewLogMsg( this.name, "==== Close log ====", 3, )) this.file.Sync() this.file.Close() }
// Close disables the BufferedLog instance, flushes any remaining entries to disk, and // then closes the backing log file. func (this *BufferedLog) Close() { this.lock.Lock() this.enabled = false this.lock.Unlock() this.print(xlog.NewLogMsg(this.name, "==== Close log ====", 2)) // stop flush routine this.chClose <- nil // flush logs this.flushLogs() // close file this.file.Close() }
// asyncFlush is run in a separate goroutine and periodically flushes // buffered entries to the backing file. func (this *BufferedLog) asyncFlush() { run := true for run { flushSec := atomic.LoadInt32(&this.flushSec) select { case <-this.chClose: run = false this.print(xlog.NewLogMsg( this.name, "Async log shutdown", 3, )) continue case <-time.After(time.Duration(flushSec) * time.Second): this.flushLogs() } } this.chClose <- nil }
// New returns a new FLog instance of the requested type. The backing log file is // created or opened for append. func New(name, logPath string, logType int) FLog { var newLog FLog mkdir(logPath) f, err := os.OpenFile( path.Join(logPath, name+".log"), FLogOpenFlags, 0660, ) if err != nil { return nil } switch logType { case BufferedFile: bLog := BufferedLog{ baseDir: logPath, chClose: make(chan interface{}, 0), enabled: true, flushSec: DefaultFlushIntervalSec, name: name, } bLog.file = f l := log.New(&bLog.buffer, "", 0) bLog.logger = l go func() { defer crash.HandleAll() bLog.asyncFlush() }() newLog = &bLog break case DirectFile: dLog := DirectLog{ baseDir: logPath, enabled: true, name: name, } dLog.file = f l := log.New(dLog.file, "", 0) dLog.logger = l newLog = &dLog break } initMsg := xlog.NewLogMsg( name, "==== Log init ====", 2, ) newLog.Print(initMsg) return newLog }