123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- package writer
- import (
- "errors"
- "fmt"
- "log"
- "os"
- "path/filepath"
- "strings"
- "time"
- )
- // timeFormat 时间格式
- // 用于文件名称格式
- const timeFormat = "2006-01-02"
- // FileWriter 文件写入结构体
- type FileWriter struct {
- file *os.File
- FilenameFunc func(*FileWriter) string
- num uint
- opts Options
- input chan []byte
- }
- // NewFileWriter 实例化FileWriter, 支持大文件分割
- func NewFileWriter(opts ...Option) (*FileWriter, error) {
- p := &FileWriter{
- opts: setDefault(),
- }
- for _, o := range opts {
- o(&p.opts)
- }
- var filename string
- var err error
- for {
- filename = p.getFilename()
- _, err := os.Stat(filename)
- if err != nil {
- if os.IsNotExist(err) {
- if p.num > 0 {
- p.num--
- filename = p.getFilename()
- }
- //文件不存在
- break
- }
- //存在,但是报错了
- return nil, err
- }
- p.num++
- if p.opts.cap == 0 {
- break
- }
- }
- p.file, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE|os.O_SYNC, 0600)
- if err != nil {
- return nil, err
- }
- p.input = make(chan []byte, 100)
- go p.write()
- return p, nil
- }
- func (p *FileWriter) write() {
- for {
- select {
- case d := <-p.input:
- _, err := p.file.Write(d)
- if err != nil {
- log.Printf("write file failed, %s\n", err.Error())
- }
- p.checkFile()
- }
- }
- }
- func (p *FileWriter) checkFile() {
- info, _ := p.file.Stat()
- if strings.Index(p.file.Name(), time.Now().Format(timeFormat)) < 0 ||
- (p.opts.cap > 0 && uint(info.Size()) > p.opts.cap) {
- //生成新文件
- if uint(info.Size()) > p.opts.cap {
- p.num++
- } else {
- p.num = 0
- }
- filename := p.getFilename()
- _ = p.file.Close()
- p.file, _ = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE|os.O_SYNC, 0600)
- }
- }
- // Write 写入方法
- func (p *FileWriter) Write(data []byte) (n int, err error) {
- if p == nil {
- return 0, errors.New("logFileWriter is nil")
- }
- if p.file == nil {
- return 0, errors.New("file not opened")
- }
- n = len(data)
- go func() {
- p.input <- data
- }()
- return n, nil
- }
- // getFilename 获取log文件名
- // 目前为:以日期格式命名,eg:2006-01-02.log or 2006-01-02.log
- func (p *FileWriter) getFilename() string {
- if p.FilenameFunc != nil {
- return p.FilenameFunc(p)
- }
- if p.opts.cap == 0 {
- return filepath.Join(p.opts.path,
- fmt.Sprintf("%s.%s",
- time.Now().Format(timeFormat),
- p.opts.suffix))
- }
- return filepath.Join(p.opts.path,
- fmt.Sprintf("%s-[%d].%s",
- time.Now().Format(timeFormat),
- p.num,
- p.opts.suffix))
- }
|