mirror of
https://github.com/fluencelabs/tendermint
synced 2025-07-27 18:21:55 +00:00
DOCKER
Godeps
INSTALL
account
alert
binary
blockchain
cmd
barak
debora
logjack
README.md
main.go
sim_txs
stdinwriter
tendermint
common
config
consensus
crawler
db
docs
events
logger
mempool
merkle
node
p2p
permission
process
rpc
scripts
state
types
vm
.gitignore
LICENSE.md
Makefile
README.md
Vagrantfile
149 lines
3.4 KiB
Go
149 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
. "github.com/tendermint/tendermint/common"
|
|
)
|
|
|
|
const Version = "0.0.1"
|
|
const sleepSeconds = 1 // Every second
|
|
|
|
// Parse command-line options
|
|
func parseFlags() (chopSize int64, limitSize int64, version bool, logFiles []string) {
|
|
var chopSizeStr, limitSizeStr string
|
|
flag.StringVar(&chopSizeStr, "chopSize", "1M", "Move file if greater than this")
|
|
flag.StringVar(&limitSizeStr, "limitSize", "1G", "Only keep this much (for each specified file). Remove old files.")
|
|
flag.BoolVar(&version, "version", false, "Version")
|
|
flag.Parse()
|
|
logFiles = flag.Args()
|
|
chopSize = parseBytesize(chopSizeStr)
|
|
limitSize = parseBytesize(limitSizeStr)
|
|
return
|
|
}
|
|
|
|
func main() {
|
|
|
|
// Read options
|
|
chopSize, limitSize, version, logFiles := parseFlags()
|
|
if version {
|
|
fmt.Println(Fmt("logjack version %v", Version))
|
|
return
|
|
}
|
|
|
|
// Print args.
|
|
// fmt.Println(chopSize, limitSiz,e version, logFiles)
|
|
|
|
go func() {
|
|
for {
|
|
for _, logFilePath := range logFiles {
|
|
minIndex, maxIndex, totalSize, baseSize := readLogInfo(logFilePath)
|
|
if chopSize < baseSize {
|
|
moveLog(logFilePath, Fmt("%v.%03d", logFilePath, maxIndex+1))
|
|
}
|
|
if limitSize < totalSize {
|
|
// NOTE: we only remove one file at a time.
|
|
removeLog(Fmt("%v.%03d", logFilePath, minIndex))
|
|
}
|
|
}
|
|
time.Sleep(sleepSeconds * time.Second)
|
|
}
|
|
}()
|
|
|
|
// Trap signal
|
|
TrapSignal(func() {
|
|
fmt.Println("logjack shutting down")
|
|
})
|
|
}
|
|
|
|
func moveLog(oldPath, newPath string) {
|
|
err := os.Rename(oldPath, newPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func removeLog(path string) {
|
|
err := os.Remove(path)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// This is a strange function. Refactor everything to make it less strange?
|
|
func readLogInfo(logPath string) (minIndex, maxIndex int, totalSize int64, baseSize int64) {
|
|
|
|
logDir := filepath.Dir(logPath)
|
|
logFile := filepath.Base(logPath)
|
|
minIndex, maxIndex = -1, -1
|
|
|
|
dir, err := os.Open(logDir)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fi, err := dir.Readdir(0)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
for _, fileInfo := range fi {
|
|
indexedFilePattern := regexp.MustCompile("^.+\\.([0-9]{3,})$")
|
|
if fileInfo.Name() == logFile {
|
|
baseSize = fileInfo.Size()
|
|
continue
|
|
} else if strings.HasPrefix(fileInfo.Name(), logFile) {
|
|
totalSize += fileInfo.Size()
|
|
submatch := indexedFilePattern.FindSubmatch([]byte(fileInfo.Name()))
|
|
if len(submatch) != 0 {
|
|
// Matches
|
|
logIndex, err := strconv.Atoi(string(submatch[1]))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if maxIndex < logIndex {
|
|
maxIndex = logIndex
|
|
}
|
|
if minIndex == -1 || logIndex < minIndex {
|
|
minIndex = logIndex
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return minIndex, maxIndex, totalSize, baseSize
|
|
}
|
|
|
|
func parseBytesize(chopSize string) int64 {
|
|
// Handle suffix multiplier
|
|
var multiplier int64 = 1
|
|
if strings.HasSuffix(chopSize, "T") {
|
|
multiplier = 1042 * 1024 * 1024 * 1024
|
|
chopSize = chopSize[:len(chopSize)-1]
|
|
}
|
|
if strings.HasSuffix(chopSize, "G") {
|
|
multiplier = 1042 * 1024 * 1024
|
|
chopSize = chopSize[:len(chopSize)-1]
|
|
}
|
|
if strings.HasSuffix(chopSize, "M") {
|
|
multiplier = 1042 * 1024
|
|
chopSize = chopSize[:len(chopSize)-1]
|
|
}
|
|
if strings.HasSuffix(chopSize, "K") {
|
|
multiplier = 1042
|
|
chopSize = chopSize[:len(chopSize)-1]
|
|
}
|
|
|
|
// Parse the numeric part
|
|
chopSizeInt, err := strconv.Atoi(chopSize)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return int64(chopSizeInt) * multiplier
|
|
}
|