fkm blog

software開発に関することを書いていきます

ローテートするWriter

Goのlogは出力先としてio.Writerを与えることができる. なのでos.Fileを開いて渡すとファイルに書いてくれる.

でもローテートまではやってくれないので, こんなの書いてみた.

type rotateWriter struct {
	fileName string
	day      int
	writer   io.WriteCloser
}

func (w *rotateWriter) Write(p []byte) (int, error) {
	now := time.Now()
	today := now.Day()
	if w.day != today {
		w.day = today
		year := now.Year()
		month := now.Month()
		fileName := fmt.Sprintf("%s_%d%02d%02d.log",
			w.fileName, year, month, today)
		if w.writer != nil {
			w.writer.Close()
		}
		w.writer, _ = os.OpenFile(fileName,
			os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	}
	return w.writer.Write(p)
}

日付が変わった後, loggerからWriteが呼ばれた時点で次のファイルを開く作戦. 複数goroutineから呼ぶと多分死ぬ.