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"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TrapSignal(cb func()) {
|
func TrapSignal(cb func()) {
|
||||||
@ -96,3 +98,101 @@ func WriteFileAtomic(filePath string, newBytes []byte) error {
|
|||||||
err = os.Rename(filePath+".new", filePath)
|
err = os.Rename(filePath+".new", filePath)
|
||||||
return err
|
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"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
. "github.com/tendermint/tendermint/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Process struct {
|
type Process struct {
|
||||||
@ -20,7 +22,7 @@ type Process struct {
|
|||||||
OutputPath string
|
OutputPath string
|
||||||
Cmd *exec.Cmd `json:"-"`
|
Cmd *exec.Cmd `json:"-"`
|
||||||
ExitState *os.ProcessState `json:"-"`
|
ExitState *os.ProcessState `json:"-"`
|
||||||
OutputFile *os.File `json:"-"`
|
OutputFile *AutoFile `json:"-"`
|
||||||
WaitCh chan struct{} `json:"-"`
|
WaitCh chan struct{} `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ const (
|
|||||||
// execPath: command name
|
// execPath: command name
|
||||||
// args: args to command. (should not include 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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user