Browse Source

Process's OutFile is an AutoFile. Use with LogRotate for Barak logs

pull/102/head
Jae Kwon 10 years ago
parent
commit
5734496819
2 changed files with 104 additions and 2 deletions
  1. +100
    -0
      common/os.go
  2. +4
    -2
      process/process.go

+ 100
- 0
common/os.go View File

@ -5,6 +5,8 @@ import (
"io/ioutil"
"os"
"os/signal"
"sync"
"time"
)
func TrapSignal(cb func()) {
@ -96,3 +98,101 @@ func WriteFileAtomic(filePath string, newBytes []byte) error {
err = os.Rename(filePath+".new", filePath)
return err
}
//--------------------------------------------------------------------------------
/* AutoFile usage
// Create/Append to ./autofile_test
af, err := OpenAutoFile("autofile_test")
if err != nil {
panic(err)
}
// Stream of writes.
// During this time, the file may be moved e.g. by logRotate.
for i := 0; i < 60; i++ {
af.Write([]byte(Fmt("LOOP(%v)", i)))
time.Sleep(time.Second)
}
// Close the AutoFile
err = af.Close()
if err != nil {
panic(err)
}
*/
const autoFileOpenDuration = 1000 * time.Millisecond
// Automatically closes and re-opens file for writing.
// This is useful for using a log file with the logrotate tool.
type AutoFile struct {
Path string
ticker *time.Ticker
mtx sync.Mutex
file *os.File
}
func OpenAutoFile(path string) (af *AutoFile, err error) {
af = &AutoFile{
Path: path,
ticker: time.NewTicker(autoFileOpenDuration),
}
if err = af.openFile(); err != nil {
return
}
go af.processTicks()
return
}
func (af *AutoFile) Close() error {
af.ticker.Stop()
af.mtx.Lock()
err := af.closeFile()
af.mtx.Unlock()
return err
}
func (af *AutoFile) processTicks() {
for {
_, ok := <-af.ticker.C
if !ok {
return // Done.
}
fmt.Println("closeFile()")
af.mtx.Lock()
af.closeFile()
af.mtx.Unlock()
}
}
func (af *AutoFile) closeFile() (err error) {
file := af.file
if file == nil {
return nil
}
af.file = nil
return file.Close()
}
func (af *AutoFile) Write(b []byte) (n int, err error) {
af.mtx.Lock()
defer af.mtx.Unlock()
if af.file == nil {
if err = af.openFile(); err != nil {
return
}
}
fmt.Println("Write:", string(b))
return af.file.Write(b)
}
func (af *AutoFile) openFile() error {
file, err := os.OpenFile(af.Path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
if err != nil {
return err
}
af.file = file
return nil
}

+ 4
- 2
process/process.go View File

@ -8,6 +8,8 @@ import (
"os"
"os/exec"
"time"
. "github.com/tendermint/tendermint/common"
)
type Process struct {
@ -20,7 +22,7 @@ type Process struct {
OutputPath string
Cmd *exec.Cmd `json:"-"`
ExitState *os.ProcessState `json:"-"`
OutputFile *os.File `json:"-"`
OutputFile *AutoFile `json:"-"`
WaitCh chan struct{} `json:"-"`
}
@ -32,7 +34,7 @@ const (
// execPath: command name
// args: args to command. (should not include name)
func Create(mode int, label string, execPath string, args []string, input string, outPath string) (*Process, error) {
outFile, err := os.OpenFile(outPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
outFile, err := OpenAutoFile(outPath)
if err != nil {
return nil, err
}


Loading…
Cancel
Save