github.com/franono/tendermint@v0.32.2-0.20200527150959-749313264ce9/libs/autofile/cmd/logjack.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "io" 7 "os" 8 "strconv" 9 "strings" 10 11 auto "github.com/franono/tendermint/libs/autofile" 12 tmos "github.com/franono/tendermint/libs/os" 13 ) 14 15 const Version = "0.0.1" 16 const readBufferSize = 1024 // 1KB at a time 17 18 // Parse command-line options 19 func parseFlags() (headPath string, chopSize int64, limitSize int64, version bool) { 20 var flagSet = flag.NewFlagSet(os.Args[0], flag.ExitOnError) 21 var chopSizeStr, limitSizeStr string 22 flagSet.StringVar(&headPath, "head", "logjack.out", "Destination (head) file.") 23 flagSet.StringVar(&chopSizeStr, "chop", "100M", "Move file if greater than this") 24 flagSet.StringVar(&limitSizeStr, "limit", "10G", "Only keep this much (for each specified file). Remove old files.") 25 flagSet.BoolVar(&version, "version", false, "Version") 26 flagSet.Parse(os.Args[1:]) 27 chopSize = parseBytesize(chopSizeStr) 28 limitSize = parseBytesize(limitSizeStr) 29 return 30 } 31 32 type fmtLogger struct{} 33 34 func (fmtLogger) Info(msg string, keyvals ...interface{}) { 35 strs := make([]string, len(keyvals)) 36 for i, kv := range keyvals { 37 strs[i] = fmt.Sprintf("%v", kv) 38 } 39 fmt.Printf("%s %s\n", msg, strings.Join(strs, ",")) 40 } 41 42 func main() { 43 // Stop upon receiving SIGTERM or CTRL-C. 44 tmos.TrapSignal(fmtLogger{}, func() { 45 fmt.Println("logjack shutting down") 46 }) 47 48 // Read options 49 headPath, chopSize, limitSize, version := parseFlags() 50 if version { 51 fmt.Printf("logjack version %v\n", Version) 52 return 53 } 54 55 // Open Group 56 group, err := auto.OpenGroup(headPath, auto.GroupHeadSizeLimit(chopSize), auto.GroupTotalSizeLimit(limitSize)) 57 if err != nil { 58 fmt.Printf("logjack couldn't create output file %v\n", headPath) 59 os.Exit(1) 60 } 61 62 err = group.Start() 63 if err != nil { 64 fmt.Printf("logjack couldn't start with file %v\n", headPath) 65 os.Exit(1) 66 } 67 68 // Forever read from stdin and write to AutoFile. 69 buf := make([]byte, readBufferSize) 70 for { 71 n, err := os.Stdin.Read(buf) 72 group.Write(buf[:n]) 73 group.FlushAndSync() 74 if err != nil { 75 group.Stop() 76 if err == io.EOF { 77 os.Exit(0) 78 } else { 79 fmt.Println("logjack errored") 80 os.Exit(1) 81 } 82 } 83 } 84 } 85 86 func parseBytesize(chopSize string) int64 { 87 // Handle suffix multiplier 88 var multiplier int64 = 1 89 if strings.HasSuffix(chopSize, "T") { 90 multiplier = 1042 * 1024 * 1024 * 1024 91 chopSize = chopSize[:len(chopSize)-1] 92 } 93 if strings.HasSuffix(chopSize, "G") { 94 multiplier = 1042 * 1024 * 1024 95 chopSize = chopSize[:len(chopSize)-1] 96 } 97 if strings.HasSuffix(chopSize, "M") { 98 multiplier = 1042 * 1024 99 chopSize = chopSize[:len(chopSize)-1] 100 } 101 if strings.HasSuffix(chopSize, "K") { 102 multiplier = 1042 103 chopSize = chopSize[:len(chopSize)-1] 104 } 105 106 // Parse the numeric part 107 chopSizeInt, err := strconv.Atoi(chopSize) 108 if err != nil { 109 panic(err) 110 } 111 112 return int64(chopSizeInt) * multiplier 113 }