Skip to content

Instantly share code, notes, and snippets.

@wtnb75
Last active August 29, 2015 14:13
Show Gist options
  • Save wtnb75/1bf320e2483c195f12a6 to your computer and use it in GitHub Desktop.
Save wtnb75/1bf320e2483c195f12a6 to your computer and use it in GitHub Desktop.
/some/program | go run rotatewriter.go /path/to/out.%Y%m-%d%H
package main
import (
"bitbucket.org/tebeka/strftime"
"io"
"log"
"os"
"os/exec"
"strings"
"time"
)
type RotateWriter struct {
Filename string
LinkTo string
CompressCmd string
curname string
outfp *os.File
}
func NewRotateWriter(outfn string) *RotateWriter {
return &RotateWriter{Filename: outfn}
}
func (w *RotateWriter) CurrentName() string {
r, err := strftime.Format(w.Filename, time.Now())
if err != nil {
log.Println("strftime", err)
return w.Filename
}
return r
}
func (w *RotateWriter) OnOpen(fn string) {
log.Println("onopen", w.LinkTo, fn)
if w.LinkTo != "" {
if err := os.Remove(w.LinkTo); err != nil {
log.Println("remove", err)
}
if err := os.Link(fn, w.LinkTo); err != nil {
log.Println("link", err)
}
}
}
func (w *RotateWriter) OnClose(fn string) {
log.Println("onclose", w.CompressCmd, fn)
if w.CompressCmd != "" {
cmds := strings.Split(w.CompressCmd, " ")
cmds = append(cmds, fn)
log.Println("cmd", cmds)
cmd := exec.Command(cmds[0], cmds[1:len(cmds)]...)
if s, err := cmd.CombinedOutput(); err != nil {
log.Println("cmd error", s, err)
} else {
log.Println("cmd result", s)
}
log.Println("onclose", w.CompressCmd, fn)
}
}
func (w *RotateWriter) Write(p []byte) (n int, err error) {
ofn := w.CurrentName()
if w.curname != ofn && w.outfp != nil {
log.Println("closing", w.curname)
fp := w.outfp
w.outfp = nil
go func(f *os.File, w *RotateWriter, curname string) {
f.Close()
w.OnClose(curname)
}(fp, w, w.curname)
}
if w.outfp == nil {
log.Println("open", ofn)
w.outfp, err = os.OpenFile(ofn, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
w.curname = ofn
w.OnOpen(ofn)
}
return w.outfp.Write(p)
}
func main() {
wr := NewRotateWriter(os.Args[1])
wr.CompressCmd = "xz"
if len(os.Args) > 2 {
wr.LinkTo = os.Args[2]
}
io.Copy(wr, os.Stdin)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment