mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-27 11:41:39 +00:00
Process's OutFile is an AutoFile. Use with LogRotate for Barak logs
This commit is contained in:
100
common/os.go
100
common/os.go
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user