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.

132 lines
3.0 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. package main
  2. import (
  3. "context"
  4. "flag"
  5. "fmt"
  6. "github.com/chrislusf/seaweedfs/weed/operation"
  7. "github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
  8. "github.com/chrislusf/seaweedfs/weed/security"
  9. weed_server "github.com/chrislusf/seaweedfs/weed/server"
  10. "github.com/chrislusf/seaweedfs/weed/storage"
  11. "github.com/spf13/viper"
  12. "golang.org/x/tools/godoc/util"
  13. "google.golang.org/grpc"
  14. "io"
  15. "log"
  16. )
  17. var (
  18. master = flag.String("master", "localhost:9333", "master server host and port")
  19. volumeId = flag.Int("volumeId", -1, "a volume id")
  20. timeoutSeconds = flag.Int("timeoutSeconds", 0, "disconnect if no activity after these seconds")
  21. showTextFile = flag.Bool("showTextFile", false, "display textual file content")
  22. )
  23. func main() {
  24. flag.Parse()
  25. weed_server.LoadConfiguration("security", false)
  26. grpcDialOption := security.LoadClientTLS(viper.Sub("grpc"), "client")
  27. vid := storage.VolumeId(*volumeId)
  28. err := TailVolume(*master, grpcDialOption, vid, func(n *storage.Needle) (err error) {
  29. if n.Size == 0 {
  30. println("-", n.String())
  31. return nil
  32. } else {
  33. println("+", n.String())
  34. }
  35. if *showTextFile {
  36. data := n.Data
  37. if n.IsGzipped() {
  38. if data, err = operation.UnGzipData(data); err != nil {
  39. return err
  40. }
  41. }
  42. if util.IsText(data) {
  43. println(string(data))
  44. }
  45. println("-", n.String(), "compressed", n.IsGzipped(), "original size", len(data))
  46. }
  47. return nil
  48. })
  49. if err != nil {
  50. log.Printf("Error VolumeTail volume %d: %v", vid, err)
  51. }
  52. }
  53. func TailVolume(master string, grpcDialOption grpc.DialOption, vid storage.VolumeId, fn func(n *storage.Needle) error) error {
  54. // find volume location, replication, ttl info
  55. lookup, err := operation.Lookup(master, vid.String())
  56. if err != nil {
  57. return fmt.Errorf("Error looking up volume %d: %v", vid, err)
  58. }
  59. if len(lookup.Locations) == 0 {
  60. return fmt.Errorf("unable to locate volume %d", vid)
  61. }
  62. volumeServer := lookup.Locations[0].Url
  63. return operation.WithVolumeServerClient(volumeServer, grpcDialOption, func(client volume_server_pb.VolumeServerClient) error {
  64. stream, err := client.VolumeTail(context.Background(), &volume_server_pb.VolumeTailRequest{
  65. VolumeId: uint32(vid),
  66. SinceNs: 0,
  67. DrainingSeconds: uint32(*timeoutSeconds),
  68. })
  69. if err != nil {
  70. return err
  71. }
  72. for {
  73. resp, recvErr := stream.Recv()
  74. if recvErr != nil {
  75. if recvErr == io.EOF {
  76. break
  77. } else {
  78. return recvErr
  79. }
  80. }
  81. needleHeader := resp.NeedleHeader
  82. needleBody := resp.NeedleBody
  83. if len(needleHeader) == 0 {
  84. continue
  85. }
  86. for !resp.IsLastChunk {
  87. resp, recvErr = stream.Recv()
  88. if recvErr != nil {
  89. if recvErr == io.EOF {
  90. break
  91. } else {
  92. return recvErr
  93. }
  94. }
  95. needleBody = append(needleBody, resp.NeedleBody...)
  96. }
  97. n := new(storage.Needle)
  98. n.ParseNeedleHeader(needleHeader)
  99. n.ReadNeedleBodyBytes(needleBody, storage.CurrentVersion)
  100. err = fn(n)
  101. if err != nil {
  102. return err
  103. }
  104. }
  105. return nil
  106. })
  107. }