github.com/pachyderm/pachyderm@v1.13.4/src/server/debug/cmds/cmds.go (about) 1 package cmds 2 3 import ( 4 "os" 5 "time" 6 7 "github.com/gogo/protobuf/types" 8 "github.com/pachyderm/pachyderm/src/client" 9 "github.com/pachyderm/pachyderm/src/client/debug" 10 "github.com/pachyderm/pachyderm/src/client/pkg/errors" 11 "github.com/pachyderm/pachyderm/src/client/pps" 12 "github.com/pachyderm/pachyderm/src/server/pkg/cmdutil" 13 "github.com/spf13/cobra" 14 ) 15 16 // Cmds returns a slice containing debug commands. 17 func Cmds() []*cobra.Command { 18 var commands []*cobra.Command 19 20 var duration time.Duration 21 var pachd bool 22 var pipeline string 23 var worker string 24 profile := &cobra.Command{ 25 Use: "{{alias}} <profile> <file>", 26 Short: "Collect a set of pprof profiles.", 27 Long: "Collect a set of pprof profiles.", 28 Run: cmdutil.RunFixedArgs(2, func(args []string) error { 29 client, err := client.NewOnUserMachine("debug-profile") 30 if err != nil { 31 return err 32 } 33 defer client.Close() 34 var d *types.Duration 35 if duration != 0 { 36 d = types.DurationProto(duration) 37 } 38 p := &debug.Profile{ 39 Name: args[0], 40 Duration: d, 41 } 42 filter, err := createFilter(pachd, pipeline, worker) 43 if err != nil { 44 return err 45 } 46 return withFile(args[1], func(f *os.File) error { 47 return client.Profile(p, filter, f) 48 }) 49 }), 50 } 51 profile.Flags().DurationVarP(&duration, "duration", "d", time.Minute, "Duration to run a CPU profile for.") 52 profile.Flags().BoolVar(&pachd, "pachd", false, "Only collect the profile from pachd.") 53 profile.Flags().StringVarP(&pipeline, "pipeline", "p", "", "Only collect the profile from the worker pods for the given pipeline.") 54 profile.Flags().StringVarP(&worker, "worker", "w", "", "Only collect the profile from the given worker pod.") 55 commands = append(commands, cmdutil.CreateAlias(profile, "debug profile")) 56 57 binary := &cobra.Command{ 58 Use: "{{alias}} <file>", 59 Short: "Collect a set of binaries.", 60 Long: "Collect a set of binaries.", 61 Run: cmdutil.RunFixedArgs(1, func(args []string) error { 62 client, err := client.NewOnUserMachine("debug-binary") 63 if err != nil { 64 return err 65 } 66 defer client.Close() 67 filter, err := createFilter(pachd, pipeline, worker) 68 if err != nil { 69 return err 70 } 71 return withFile(args[0], func(f *os.File) error { 72 return client.Binary(filter, f) 73 }) 74 }), 75 } 76 binary.Flags().BoolVar(&pachd, "pachd", false, "Only collect the binary from pachd.") 77 binary.Flags().StringVarP(&pipeline, "pipeline", "p", "", "Only collect the binary from the worker pods for the given pipeline.") 78 binary.Flags().StringVarP(&worker, "worker", "w", "", "Only collect the binary from the given worker pod.") 79 commands = append(commands, cmdutil.CreateAlias(binary, "debug binary")) 80 81 var limit int64 82 dump := &cobra.Command{ 83 Use: "{{alias}} <file>", 84 Short: "Collect a standard set of debugging information.", 85 Long: "Collect a standard set of debugging information.", 86 Run: cmdutil.RunFixedArgs(1, func(args []string) error { 87 client, err := client.NewOnUserMachine("debug-dump") 88 if err != nil { 89 return err 90 } 91 defer client.Close() 92 filter, err := createFilter(pachd, pipeline, worker) 93 if err != nil { 94 return err 95 } 96 return withFile(args[0], func(f *os.File) error { 97 return client.Dump(filter, limit, f) 98 }) 99 }), 100 } 101 dump.Flags().BoolVar(&pachd, "pachd", false, "Only collect the dump from pachd.") 102 dump.Flags().StringVarP(&pipeline, "pipeline", "p", "", "Only collect the dump from the worker pods for the given pipeline.") 103 dump.Flags().StringVarP(&worker, "worker", "w", "", "Only collect the dump from the given worker pod.") 104 dump.Flags().Int64VarP(&limit, "limit", "l", 0, "Limit sets the limit for the number of commits / jobs that are returned for each repo / pipeline in the dump.") 105 commands = append(commands, cmdutil.CreateAlias(dump, "debug dump")) 106 107 debug := &cobra.Command{ 108 Short: "Debug commands for analyzing a running cluster.", 109 Long: "Debug commands for analyzing a running cluster.", 110 } 111 commands = append(commands, cmdutil.CreateAlias(debug, "debug")) 112 113 return commands 114 } 115 116 func createFilter(pachd bool, pipeline, worker string) (*debug.Filter, error) { 117 var f *debug.Filter 118 if pachd { 119 f = &debug.Filter{Filter: &debug.Filter_Pachd{Pachd: true}} 120 } 121 if pipeline != "" { 122 if f != nil { 123 return nil, errors.Errorf("only one debug filter allowed") 124 } 125 f = &debug.Filter{Filter: &debug.Filter_Pipeline{&pps.Pipeline{Name: pipeline}}} 126 } 127 if worker != "" { 128 if f != nil { 129 return nil, errors.Errorf("only one debug filter allowed") 130 } 131 f = &debug.Filter{Filter: &debug.Filter_Worker{&debug.Worker{Pod: worker}}} 132 } 133 return f, nil 134 } 135 136 func withFile(file string, cb func(*os.File) error) (retErr error) { 137 f, err := os.Create(file) 138 if err != nil { 139 return err 140 } 141 defer func() { 142 if err := f.Close(); retErr == nil { 143 retErr = err 144 } 145 }() 146 return cb(f) 147 }