github.com/sereiner/library@v0.0.0-20200518095232-1fa3e640cc5f/log/appender.file.go (about)

     1  package log
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"sync"
     7  	"time"
     8  
     9  	"fmt"
    10  
    11  	"github.com/sereiner/library/file"
    12  )
    13  
    14  //FileAppender 文件输出器
    15  type FileAppender struct {
    16  	name      string
    17  	buffer    *bytes.Buffer
    18  	lastWrite time.Time
    19  	layout    *Appender
    20  	file      io.WriteCloser
    21  	ticker    *time.Ticker
    22  	locker    sync.Mutex
    23  	Level     int
    24  }
    25  
    26  //NewFileAppender 构建基于文件流的日志输出对象
    27  func NewFileAppender(path string, layout *Appender) (fa *FileAppender, err error) {
    28  	fa = &FileAppender{layout: layout}
    29  	fa.Level = GetLevel(layout.Level)
    30  	fa.buffer = bytes.NewBufferString("\n--------------------begin------------------------\n\n")
    31  	intervalStr := layout.Interval
    32  	if intervalStr == "" {
    33  		intervalStr = "1s"
    34  	}
    35  	interval, err := time.ParseDuration(intervalStr)
    36  	if err != nil {
    37  		err = fmt.Errorf("日志配置文件错误:%v", err)
    38  		return
    39  	}
    40  	fa.ticker = time.NewTicker(interval)
    41  	fa.file, err = file.CreateFile(path)
    42  	if err != nil {
    43  		return
    44  	}
    45  	go fa.writeTo()
    46  	return
    47  }
    48  
    49  //Write 写入日志
    50  func (f *FileAppender) Write(event *LogEvent) {
    51  	current := GetLevel(event.Level)
    52  	if current < f.Level {
    53  		return
    54  	}
    55  	f.locker.Lock()
    56  	f.buffer.WriteString(event.Output)
    57  	f.locker.Unlock()
    58  	f.lastWrite = time.Now()
    59  }
    60  
    61  //Close 关闭当前appender
    62  func (f *FileAppender) Close() {
    63  	f.Level = ILevel_OFF
    64  	f.ticker.Stop()
    65  	f.locker.Lock()
    66  	f.buffer.WriteString("\n---------------------end-------------------------\n")
    67  	f.buffer.WriteTo(f.file)
    68  	f.file.Close()
    69  	f.locker.Unlock()
    70  }
    71  
    72  //writeTo 定时写入文件
    73  func (f *FileAppender) writeTo() {
    74  START:
    75  	for {
    76  		select {
    77  		case _, ok := <-f.ticker.C:
    78  			if ok {
    79  				f.locker.Lock()
    80  				f.buffer.WriteTo(f.file)
    81  				f.buffer.Reset()
    82  				f.locker.Unlock()
    83  			} else {
    84  				break START
    85  			}
    86  		}
    87  	}
    88  }