You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
2.5 KiB

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