go写一个简单的文件修改监听

logger文件

package src

import (
    "fmt"
    "os"
    "path/filepath"
    "strings"
    "sync"
    "time"
)

type File struct {
    sync.RWMutex
    // 文件名
    fileName     string
    suffix       string
    fileNameOnly string
    // 是否已经初始化
    init bool
    // 写入的文件
    // fileWriter *os.File
    fileWriters []*os.File
    // 日期
    daily         bool
    dailyOpenDate int
    dailyOpenTime time.Time
}

// 初始化
func (bl *File) Init(fileName string) {
    bl.Lock()
    bl.fileName = fileName
    bl.suffix = filepath.Ext(bl.fileName)
    bl.fileNameOnly = strings.TrimSuffix(bl.fileName, bl.suffix)
    if bl.suffix == "" {
        bl.suffix = ".log"
    }

    // 创建文件
    var fileWriters = []*os.File{nil, os.Stdout}
    // os.O_TRUNC|
    file, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
    if err != nil {
        _ = fmt.Errorf("文件%s异常,%v", fileName, err)
        if os.IsNotExist(err) {
            file, err := os.Create(fileName)
            if err != nil {
                fmt.Println(err)
            } else {
                fileWriters[0] = file
            }
        } else {
            fmt.Printf("创建文件%s失败", fileName)
        }
    } else {
        fileWriters[0] = file
    }
    bl.fileWriters = fileWriters
    // 日期
    bl.daily = true
    bl.dailyOpenTime = time.Now()
    bl.dailyOpenDate = bl.dailyOpenTime.Day()

    bl.init = true
    bl.Unlock()
}

// 自己的写文件接口
func (bl *File) writeMsg(msg string, v ...interface{}) {
    if !bl.init {
        panic("未初始化")
    }
    if len(v) > 0 {
        msg = fmt.Sprintf(msg, v...)
    }

    now := time.Now()
    if bl.needRotateDaily(now.Day()) {
        bl.Lock()
        bl.doRotate(now)
        bl.Unlock()
    }

    // 写入文件
    for _, fw := range bl.fileWriters {
        _, err := fw.WriteString(msg)
        if err != nil {
            _, _ = fmt.Fprintf(os.Stderr, "error:%v\n", err)
        }
    }
}

// 实现is.Write接口
func (bl *File) Write(p []byte) (n int, err error) {
    if len(p) == 0 {
        return 0, nil
    }
    // set levelLoggerImpl to ensure all log message will be write out
    bl.writeMsg(string(p))
    return 0, err
}

func (bl *File) needRotateDaily(day int) bool {
    return bl.daily && day != bl.dailyOpenDate
}

func (bl *File) doRotate(logTime time.Time) {
    var format = "20060102"
    var fName = bl.fileNameOnly + fmt.Sprintf(".%s%s", logTime.Format(format), bl.suffix)
    err := bl.fileWriters[0].Close()
    if err != nil {
        _, _ = fmt.Fprintf(os.Stderr, "error:%v\n", err)
    }
    err = os.Rename(bl.fileName, fName)
    if err != nil {
        _, _ = fmt.Fprintf(os.Stderr, "error:%v\n", err)
    }

    file, err := os.OpenFile(bl.fileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
    if err != nil {
        _ = fmt.Errorf("文件%s异常,%v", bl.fileName, err)
        if os.IsNotExist(err) {
            file, err := os.Create(bl.fileName)
            if err != nil {
                fmt.Println(err)
            } else {
                bl.fileWriters[0] = file
            }
        } else {
            fmt.Printf("创建文件%s失败", bl.fileName)
        }
    } else {
        bl.fileWriters[0] = file
    }

    bl.dailyOpenTime = logTime
    bl.dailyOpenDate = bl.dailyOpenTime.Day()
}

main文件

package main

import (
    "FileMonitor/src"
    "flag"
    "github.com/fsnotify/fsnotify"
    "log"
)

var logFile *src.File
var path string

func init() {
    logFile = new(src.File)
    logFile.Init("monitor.log")
    log.SetOutput(logFile)
    flag.StringVar(&path, "p", "", "monitor `path`")
}

func main() {
    flag.Parse()
    if path == "" {
        log.Printf("path is null")
        return
    }

    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer closeWatcher(watcher)

    done := make(chan bool)
    go func() {
        for {
            select {
            case event := <-watcher.Events:
                if event.Op&fsnotify.Write == fsnotify.Write {
                    log.Println("modified file:", event.Name)
                }
            case err := <-watcher.Errors:
                log.Println("error:", err)
            }
        }
    }()

    err = watcher.Add(path)
    if err != nil {
        log.Fatal(err)
    }
    <-done
}

func closeWatcher(watcher *fsnotify.Watcher) {
    if watcher != nil {
        e := watcher.Close()
        if e != nil {
            log.Printf("error:%v\n", e)
        }
    }
}