veyron/tools/debug: Add vtrace support to the debug client command.
Change-Id: I47c89b02ac6e42c6e3329609fe2550c2a342fe96
diff --git a/tools/debug/impl.go b/tools/debug/impl.go
index f3dc121..f15adf3 100644
--- a/tools/debug/impl.go
+++ b/tools/debug/impl.go
@@ -24,9 +24,12 @@
logtypes "veyron.io/veyron/veyron2/services/mgmt/logreader/types"
"veyron.io/veyron/veyron2/services/mgmt/pprof"
"veyron.io/veyron/veyron2/services/mgmt/stats"
+ vtracesvc "veyron.io/veyron/veyron2/services/mgmt/vtrace"
"veyron.io/veyron/veyron2/services/watch"
watchtypes "veyron.io/veyron/veyron2/services/watch/types"
+ "veyron.io/veyron/veyron2/uniqueid"
"veyron.io/veyron/veyron2/vom"
+ "veyron.io/veyron/veyron2/vtrace"
)
var (
@@ -60,6 +63,81 @@
cmdPProfRun.Flags.StringVar(&pprofCmd, "pprofcmd", "veyron go tool pprof", "The pprof command to use.")
}
+var cmdVtrace = &cmdline.Command{
+ Run: runVtrace,
+ Name: "vtrace",
+ Short: "Returns vtrace traces.",
+ Long: "Returns matching vtrace traces (or all stored traces if no ids are given).",
+ ArgsName: "<name> [id ...]",
+ ArgsLong: `
+<name> is the name of a vtrace object.
+[id] is a vtrace trace id.
+`,
+}
+
+func doFetchTrace(ctx context.T, wg *sync.WaitGroup, client vtracesvc.StoreClientStub,
+ id uniqueid.ID, traces chan *vtrace.TraceRecord, errors chan error) {
+ defer wg.Done()
+
+ trace, err := client.Trace(ctx, id)
+ if err != nil {
+ errors <- err
+ } else {
+ traces <- &trace
+ }
+}
+
+func runVtrace(cmd *cmdline.Command, args []string) error {
+ ctx := rt.R().NewContext()
+ arglen := len(args)
+ if arglen == 0 {
+ return cmd.UsageErrorf("vtrace: incorrect number of arguments, got %d want >= 1", arglen)
+ }
+
+ name := args[0]
+ client := vtracesvc.StoreClient(name)
+ if arglen == 1 {
+ call, err := client.AllTraces(ctx)
+ if err != nil {
+ return err
+ }
+ stream := call.RecvStream()
+ for stream.Advance() {
+ trace := stream.Value()
+ vtrace.FormatTrace(os.Stdout, &trace, nil)
+ }
+ if err := stream.Err(); err != nil {
+ return err
+ }
+ return call.Finish()
+ }
+
+ ntraces := len(args) - 1
+ traces := make(chan *vtrace.TraceRecord, ntraces)
+ errors := make(chan error, ntraces)
+ var wg sync.WaitGroup
+ wg.Add(ntraces)
+ for _, arg := range args[1:] {
+ id, err := uniqueid.FromHexString(arg)
+ if err != nil {
+ return err
+ }
+ go doFetchTrace(ctx, &wg, client, id, traces, errors)
+ }
+ go func() {
+ wg.Wait()
+ close(traces)
+ close(errors)
+ }()
+
+ for trace := range traces {
+ vtrace.FormatTrace(os.Stdout, trace, nil)
+ }
+
+ // Just return one of the errors.
+ return <-errors
+}
+
var cmdGlob = &cmdline.Command{
Run: runGlob,
Name: "glob",
@@ -487,6 +565,7 @@
Long: "Command-line tool for interacting with the debug server.",
Children: []*cmdline.Command{
cmdGlob,
+ cmdVtrace,
&cmdline.Command{
Name: "logs",
Short: "Accesses log files",