package gologger import ( "os" "path/filepath" ) type FileAppender struct { filePath string lchan chan LogEvent file *os.File stopChan chan struct{} } // Close implements LoggerAppender. func (f *FileAppender) Close() { //send stop signal f.stopChan <- struct{}{} } func (f *FileAppender) GetName() string { return "FileAppender:" + f.filePath } func (f *FileAppender) start() { f.lchan = make(chan LogEvent, 10) f.stopChan = make(chan struct{}) if f.file == nil || int(f.file.Fd()) == -1 { dirName := filepath.Dir(f.filePath) _, err := os.Stat(dirName) if err != nil && os.IsNotExist(err) { os.MkdirAll(dirName, 0755) } f.file, _ = os.OpenFile(f.filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) } go func() { defer f.file.Close() for { select { case <-f.stopChan: return case logEvent := <-f.lchan: logMsg := format(logEvent) f.file.WriteString(logMsg) } } }() } func (f *FileAppender) Append(logEvent LogEvent) { f.lchan <- logEvent } func makeFileAppender(appenderConfig LogAppenderConfig) *LoggerAppender { var logfile interface{} var ok bool logfile, ok = appenderConfig.Options["file"] if !ok { logfile = "default.log" } var ret LoggerAppender = &FileAppender{ filePath: logfile.(string), } ret.(*FileAppender).start() return &ret } func init() { RegistAppender("file", makeFileAppender) }