Goのログローテーションはlumberjackというイメージがあったが、2024/12時点で1年以上更新がない
とりあえずio.Writerにファイルをリロードするインタフェースを追加したら使い勝手が良さそうかなと思ったので実装してみた
実装
type RFWriter interface {
io.WriteCloser
Reload() error
}
やりたいこと的に書き込み対象がファイルなのでインタフェースではio.WriteCloserを採用
プラスアルファでリロードしたいときに呼び出すReload()
メソッドを定義
動作確認
↓サンプル
package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/Haya372/go-rfwriter"
)
func main() {
w, err := rfwriter.NewRFWriter("example.txt")
if err != nil {
os.Exit(1)
}
defer w.Close()
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM)
defer stop()
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT)
go func() {
for {
fmt.Println("wait signal...")
select {
case <-ctx.Done():
fmt.Println("finish goroutine")
return
case <-sig:
fmt.Println("received signal")
w.Reload()
}
}
}()
time.Sleep(1 * time.Minute)
}
$ go run main.go
wait signal...
^Creceived signal
wait signal...
^Creceived signal
wait signal...
finish goroutine
途中でexample.txt
を削除してもSIGINTを送ればファイルが再作成されるのでリロードできてそう
動作確認しやすいようにSIGINTでリロードするようにしたけど、SIGUSR1とかでリロードするようにしておけばnginxの設定を真似てlogrotateの設定を書けばいい感じにログローテーションしてくれそう
参考