]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[release-branch.go1.22] cmd/trace/v2: emit user log annotations in all views
authorMichael Anthony Knyszek <mknyszek@google.com>
Fri, 19 Jan 2024 19:25:04 +0000 (19:25 +0000)
committerGopher Robot <gobot@golang.org>
Tue, 23 Jan 2024 19:30:57 +0000 (19:30 +0000)
This was an oversight in porting over cmd/trace to the new trace format
and API.

Fixes #65153.

Change-Id: I883d302f95956fcc9abb60aa53165acb6d099d67
Reviewed-on: https://go-review.googlesource.com/c/go/+/557175
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
(cherry picked from commit 7cb98c1da1d38447a272c50b2a33634ebb845aa4)
Reviewed-on: https://go-review.googlesource.com/c/go/+/557817
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>

src/cmd/trace/v2/gen.go
src/cmd/trace/v2/goroutinegen.go
src/cmd/trace/v2/procgen.go
src/cmd/trace/v2/threadgen.go

index ad1599db92ddae098db7577822ca3bc298be2aa2..f6a4bb643b2c1aa7a744c091e6b064a65579d1ee 100644 (file)
@@ -31,6 +31,9 @@ type generator interface {
        ProcRange(ctx *traceContext, ev *tracev2.Event)
        ProcTransition(ctx *traceContext, ev *tracev2.Event)
 
+       // User annotations.
+       Log(ctx *traceContext, ev *tracev2.Event)
+
        // Finish indicates the end of the trace and finalizes generation.
        Finish(ctx *traceContext)
 }
@@ -69,6 +72,8 @@ func runGenerator(ctx *traceContext, g generator, parsed *parsedTrace, opts *gen
                        case tracev2.ResourceGoroutine:
                                g.GoroutineTransition(ctx, ev)
                        }
+               case tracev2.EventLog:
+                       g.Log(ctx, ev)
                }
        }
        for i, task := range opts.tasks {
@@ -357,3 +362,33 @@ type completedRange struct {
        endStack   tracev2.Stack
        arg        any
 }
+
+type logEventGenerator[R resource] struct {
+       // getResource is a function to extract a resource ID from a Log event.
+       getResource func(*tracev2.Event) R
+}
+
+// Log implements a log event handler. It expects ev to be one such event.
+func (g *logEventGenerator[R]) Log(ctx *traceContext, ev *tracev2.Event) {
+       id := g.getResource(ev)
+       if id == R(noResource) {
+               // We have nowhere to put this in the UI.
+               return
+       }
+
+       // Construct the name to present.
+       log := ev.Log()
+       name := log.Message
+       if log.Category != "" {
+               name = "[" + log.Category + "] " + name
+       }
+
+       // Emit an instant event.
+       ctx.Instant(traceviewer.InstantEvent{
+               Name:     name,
+               Ts:       ctx.elapsed(ev.Time()),
+               Category: "user event",
+               Resource: uint64(id),
+               Stack:    ctx.Stack(viewerFrames(ev.Stack())),
+       })
+}
index eb1aea9bfa5ec62eeeea662b55ad2ae91f64c622..c76bd8487ae64f3fbde0e87446fcf93ca2cfee59 100644 (file)
@@ -14,6 +14,7 @@ type goroutineGenerator struct {
        globalRangeGenerator
        globalMetricGenerator
        stackSampleGenerator[tracev2.GoID]
+       logEventGenerator[tracev2.GoID]
 
        gStates map[tracev2.GoID]*gState[tracev2.GoID]
        focus   tracev2.GoID
@@ -22,9 +23,11 @@ type goroutineGenerator struct {
 
 func newGoroutineGenerator(ctx *traceContext, focus tracev2.GoID, filter map[tracev2.GoID]struct{}) *goroutineGenerator {
        gg := new(goroutineGenerator)
-       gg.stackSampleGenerator.getResource = func(ev *tracev2.Event) tracev2.GoID {
+       rg := func(ev *tracev2.Event) tracev2.GoID {
                return ev.Goroutine()
        }
+       gg.stackSampleGenerator.getResource = rg
+       gg.logEventGenerator.getResource = rg
        gg.gStates = make(map[tracev2.GoID]*gState[tracev2.GoID])
        gg.focus = focus
        gg.filter = filter
index 30ed568dadd0f9e3a694dd29fbe73c39b75e31d7..41e379527f1eaa8cc688f9c6af9e8550797bd6aa 100644 (file)
@@ -18,6 +18,7 @@ type procGenerator struct {
        globalMetricGenerator
        procRangeGenerator
        stackSampleGenerator[tracev2.ProcID]
+       logEventGenerator[tracev2.ProcID]
 
        gStates   map[tracev2.GoID]*gState[tracev2.ProcID]
        inSyscall map[tracev2.ProcID]*gState[tracev2.ProcID]
@@ -26,9 +27,11 @@ type procGenerator struct {
 
 func newProcGenerator() *procGenerator {
        pg := new(procGenerator)
-       pg.stackSampleGenerator.getResource = func(ev *tracev2.Event) tracev2.ProcID {
+       rg := func(ev *tracev2.Event) tracev2.ProcID {
                return ev.Proc()
        }
+       pg.stackSampleGenerator.getResource = rg
+       pg.logEventGenerator.getResource = rg
        pg.gStates = make(map[tracev2.GoID]*gState[tracev2.ProcID])
        pg.inSyscall = make(map[tracev2.ProcID]*gState[tracev2.ProcID])
        return pg
index c2d20719266f3667d9798a9c4d441bc93669d0b2..e1cae2b2cf93bf9d447b760a7dc17cdb333d07d5 100644 (file)
@@ -17,6 +17,7 @@ type threadGenerator struct {
        globalRangeGenerator
        globalMetricGenerator
        stackSampleGenerator[tracev2.ThreadID]
+       logEventGenerator[tracev2.ThreadID]
 
        gStates map[tracev2.GoID]*gState[tracev2.ThreadID]
        threads map[tracev2.ThreadID]struct{}
@@ -24,9 +25,11 @@ type threadGenerator struct {
 
 func newThreadGenerator() *threadGenerator {
        tg := new(threadGenerator)
-       tg.stackSampleGenerator.getResource = func(ev *tracev2.Event) tracev2.ThreadID {
+       rg := func(ev *tracev2.Event) tracev2.ThreadID {
                return ev.Thread()
        }
+       tg.stackSampleGenerator.getResource = rg
+       tg.logEventGenerator.getResource = rg
        tg.gStates = make(map[tracev2.GoID]*gState[tracev2.ThreadID])
        tg.threads = make(map[tracev2.ThreadID]struct{})
        return tg