main.go 2.0 KB

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