Add ftrace support to DebugService
This allows us to do ad-hoc kernel-level tracing on a running Metropolis node.
Useful for tracking down complex bugs.
Example: `bazel run //metropolis/cli/dbg -- trace -function_graph_filter blkdev_* function_graph`
Test Plan: Debug utility, manually tested
X-Origin-Diff: phab/D748
GitOrigin-RevId: 924eb795250412a73eb30c0eef4a8c1cc726e5fd
diff --git a/metropolis/cli/dbg/main.go b/metropolis/cli/dbg/main.go
index eb9070f..75685e9 100644
--- a/metropolis/cli/dbg/main.go
+++ b/metropolis/cli/dbg/main.go
@@ -24,6 +24,7 @@
"io/ioutil"
"math/rand"
"os"
+ "strings"
"time"
"github.com/spf13/pflag"
@@ -69,6 +70,14 @@
fmt.Fprintf(os.Stderr, "Example:\n %s %s IPAssigned\n", os.Args[0], os.Args[1])
}
+ traceCmd := flag.NewFlagSet("trace", flag.ExitOnError)
+ traceCmd.Usage = func() {
+ fmt.Fprintf(os.Stderr, "Usage: %v %v [options] tracer\n", os.Args[0], os.Args[1])
+ flag.PrintDefaults()
+ }
+ functionFilter := traceCmd.String("function_filter", "", "Only trace functions matched by this filter (comma-separated, supports wildcards via *)")
+ functionGraphFilter := traceCmd.String("function_graph_filter", "", "Only trace functions matched by this filter and their children (syntax same as function_filter)")
+
switch os.Args[1] {
case "logs":
logsCmd.Parse(os.Args[2:])
@@ -157,5 +166,37 @@
if err := command.Execute(); err != nil {
os.Exit(1)
}
+ case "trace":
+ traceCmd.Parse(os.Args[2:])
+ tracer := traceCmd.Arg(0)
+ var fgf []string
+ var ff []string
+ if len(*functionGraphFilter) > 0 {
+ fgf = strings.Split(*functionGraphFilter, ",")
+ }
+ if len(*functionFilter) > 0 {
+ ff = strings.Split(*functionFilter, ",")
+ }
+ req := apb.TraceRequest{
+ GraphFunctionFilter: fgf,
+ FunctionFilter: ff,
+ Tracer: tracer,
+ }
+ traceEvents, err := debugClient.Trace(ctx, &req)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to trace: %v", err)
+ os.Exit(1)
+ }
+ for {
+ traceEvent, err := traceEvents.Recv()
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ fmt.Fprintf(os.Stderr, "stream aborted unexpectedly: %v", err)
+ os.Exit(1)
+ }
+ fmt.Println(traceEvent.RawLine)
+ }
}
}