main.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package main
  2. import (
  3. "errors"
  4. "flag"
  5. "fmt"
  6. "log"
  7. "path"
  8. etcdserverpb "github.com/coreos/etcd/etcdserver/etcdserverpb"
  9. "github.com/coreos/etcd/migrate"
  10. "github.com/coreos/etcd/pkg/types"
  11. raftpb "github.com/coreos/etcd/raft/raftpb"
  12. "github.com/coreos/etcd/wal"
  13. "github.com/coreos/etcd/wal/walpb"
  14. )
  15. func walDir5(dataDir string) string {
  16. return path.Join(dataDir, "wal")
  17. }
  18. func logFile4(dataDir string) string {
  19. return path.Join(dataDir, "log")
  20. }
  21. func main() {
  22. version := flag.Int("version", 5, "4 or 5")
  23. from := flag.String("data-dir", "", "")
  24. flag.Parse()
  25. if *from == "" {
  26. log.Fatal("Must provide -data-dir flag")
  27. }
  28. var ents []raftpb.Entry
  29. var err error
  30. switch *version {
  31. case 4:
  32. ents, err = dump4(*from)
  33. case 5:
  34. ents, err = dump5(*from)
  35. default:
  36. err = errors.New("value of -version flag must be 4 or 5")
  37. }
  38. if err != nil {
  39. log.Fatalf("Failed decoding log: %v", err)
  40. }
  41. for _, e := range ents {
  42. msg := fmt.Sprintf("%2d %5d: ", e.Term, e.Index)
  43. switch e.Type {
  44. case raftpb.EntryNormal:
  45. msg = fmt.Sprintf("%s norm", msg)
  46. var r etcdserverpb.Request
  47. if err := r.Unmarshal(e.Data); err != nil {
  48. msg = fmt.Sprintf("%s ???", msg)
  49. } else {
  50. msg = fmt.Sprintf("%s %s %s %s", msg, r.Method, r.Path, r.Val)
  51. }
  52. case raftpb.EntryConfChange:
  53. msg = fmt.Sprintf("%s conf", msg)
  54. var r raftpb.ConfChange
  55. if err := r.Unmarshal(e.Data); err != nil {
  56. msg = fmt.Sprintf("%s ???", msg)
  57. } else {
  58. msg = fmt.Sprintf("%s %s %s %s", msg, r.Type, types.ID(r.NodeID), r.Context)
  59. }
  60. }
  61. fmt.Println(msg)
  62. }
  63. }
  64. func dump4(dataDir string) ([]raftpb.Entry, error) {
  65. lf4 := logFile4(dataDir)
  66. ents, err := migrate.DecodeLog4FromFile(lf4)
  67. if err != nil {
  68. return nil, err
  69. }
  70. return migrate.Entries4To2(ents)
  71. }
  72. func dump5(dataDir string) ([]raftpb.Entry, error) {
  73. wd5 := walDir5(dataDir)
  74. if !wal.Exist(wd5) {
  75. return nil, fmt.Errorf("No wal exists at %s", wd5)
  76. }
  77. w, err := wal.Open(wd5, walpb.Snapshot{})
  78. if err != nil {
  79. return nil, err
  80. }
  81. defer w.Close()
  82. _, _, ents, err := w.ReadAll()
  83. return ents, err
  84. }