Skip to content

Instantly share code, notes, and snippets.

@kvii
Created August 19, 2023 06:43
Show Gist options
  • Save kvii/484acc37c2a81008de8fa5ca20a17512 to your computer and use it in GitHub Desktop.
Save kvii/484acc37c2a81008de8fa5ca20a17512 to your computer and use it in GitHub Desktop.
Demo for log rotate.
package main
import (
"fmt"
"io"
"os"
)
func main() {
var i int
r := &Rotate{
Need: func() bool { return true },
New: func() (io.WriteCloser, error) {
i++
return os.Create(fmt.Sprintf("log-%d.log", i))
},
}
fmt.Fprintln(r, "Hello")
fmt.Fprintln(r, "World")
}
// Rotate 结构定义了单线程版的日志轮转结构。
// 自己用的话把检查函数和构造函数抽象一下,然后加个锁就 OK。
type Rotate struct {
cur io.WriteCloser // 当前 WriteCloser
Need func() bool // 检查函数
New func() (io.WriteCloser, error) // 构造函数
}
// Write 方法实现 [io.Writer]。
func (r *Rotate) Write(p []byte) (int, error) {
wc, err := r.load()
if err != nil {
return 0, err
}
return wc.Write(p)
}
// 如果 r.cur != nil 并且 r.Need() 返回 true 的话,就把之前的 r.cur 关闭,然后 New 一个返回。
// 如果 r.cur != nil 并且 r.Need() 返回 false 的话,就直接返回 r.cur。
// 如果 r.cur == nil,就需要 New 一个返回。
func (r *Rotate) load() (io.WriteCloser, error) {
if r.cur != nil {
if !r.Need() {
return r.cur, nil
}
err := r.cur.Close()
if err != nil {
return nil, err
}
}
wc, err := r.New()
if err != nil {
return nil, err
}
r.cur = wc
return wc, nil
}
// Close 方法实现了 [io.Closer]。
func (r *Rotate) Close() error {
if r.cur != nil {
return r.cur.Close()
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment