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.

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