forked from cockroachdb/cockroach
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tracing: add /debug/tracez rendering the active spans
/debug/tracez lets users take a snapshot of the active spans registry and render the new snapshot, or one of the previously taken snapshots. The Tracer can hold up to 10 snapshots in memory. The PR description has a screenshot. When visualizing a snapshot, the page lets you do a number of things: 1. List all the spans. 2. See the (current) stack trace for each span's goroutine (if the goroutine was still running at the time when the snapshot was captured). Stack traces can be toggled visible/hidden. 3. Sort the spans by name or start time. 4. Filter the span according to text search. The search works across the name and stack trace. 5. See the full trace that a particular span is part of. For the table Javascript providing sorting and filtering, this patch embeds the library from https://listjs.com/ . Limitations: - for now, only the registry of the local node is snapshotted. In the fuiture I'll collect info from all nodes. - for now, the relationships between different spans are not represented in any way. I'll work on the ability to go from a span to the whole trace that the span is part of. - for now, tags and structured and unstructured log messages that a span might have are not displayed in any way. At the moment, span creation is not enabled in production by default (i.e. the Tracer is put in TracingModeOnDemand by default, instead of the required TracingModeActiveSpansRegistry). This patch does not change that, so in order to benefit from /debug/tracez in all its glory, one has to run with COCKROACH_REAL_SPANS=1 for now. Not for long, though. Release note: None
- Loading branch information
1 parent
798225c
commit a2a8f02
Showing
17 changed files
with
774 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<style> | ||
.sort.asc, .sort.desc { | ||
background-color: yellow; | ||
} | ||
.sort.asc::after { | ||
content: "\002B06"; | ||
padding-left: 3px; | ||
} | ||
.sort.desc::after { | ||
content: "\002B07"; | ||
padding-left: 3px | ||
} | ||
|
||
.link-button { | ||
background: none!important; | ||
border: none; | ||
padding: 0!important; | ||
font-family: arial, sans-serif; | ||
color: #069; | ||
text-decoration: underline; | ||
cursor: pointer; | ||
} | ||
|
||
</style> | ||
</head> | ||
|
||
<script src="/debug/assets/list.min.js" type="text/javascript"></script> | ||
|
||
<a href="?snap=new">Take a snapshot of current operations</a> | ||
<div style="float:right"> | ||
Stored snapshots (ID: capture time): | ||
{{$id := .SnapshotID}} | ||
{{range $i, $s := .AllSnapshots}} | ||
<span style="{{if ne $i 0}}margin-left:0.5em;{{end}}"> | ||
{{if eq $s.ID $id}} | ||
[current] {{$s.ID}}: {{formatTimeNoMillis .CapturedAt}} | ||
{{else}} | ||
<a href="?snap={{$s.ID}}">{{$s.ID}}: {{formatTimeNoMillis .CapturedAt}}</a> | ||
{{end}} | ||
</span> | ||
{{end}} | ||
</div> | ||
|
||
<p>Spans currently open: {{len .SpansList.Spans}}. Snapshot captured at: {{formatTime .CapturedAt}} UTC. Page generated at: {{formatTime .Now}} UTC.</p> | ||
{{if ne .Err nil}} | ||
<p><b>There was an error producing this snapshot; it might be incomplete: {{.Err}}</b></p> | ||
{{end}} | ||
|
||
<div id="spans-list"> | ||
<table> | ||
<thead> | ||
<input class="search" placeholder="Search" /> | ||
<tr> | ||
<th> | ||
<button class="sort link-button" data-sort="operation"> Operation </button> | ||
</th> | ||
<th> | ||
<button class="sort link-button" data-sort="startTimeMicros"> Started at </button> | ||
</th> | ||
<th> | ||
<button class="sort link-button" data-sort="goroutineID"> Goroutine ID </button> | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody class="list"> | ||
<!-- This will be populated by spansList. --> | ||
</tbody> | ||
</table> | ||
</div> | ||
|
||
<script> | ||
|
||
// Some fields are strings because JS doesn't do 64-bit numbers properly. | ||
var values = [ | ||
{{$capturedAt := .CapturedAt}} | ||
{{$stacks := .SpansList.Stacks}} | ||
{{range .SpansList.Spans}} | ||
{ | ||
operation: {{.Operation}}, | ||
spanID: "{{.SpanID}}", | ||
startTime: {{formatTime .StartTime}}, | ||
relativeTime: {{since .StartTime $capturedAt}}, | ||
startTimeMicros: {{timeRaw .StartTime}}, | ||
goroutineID: {{.GoroutineID}}, | ||
traceID: "{{.TraceID}}", | ||
stack: {{index $stacks .GoroutineID}} | ||
}, | ||
{{end}} | ||
]; | ||
|
||
function toggleStackVisibility(spanID) { | ||
var div = document.getElementById("stack-"+spanID); | ||
if (div.style.display === "none") { | ||
div.style.display = "block"; | ||
} else { | ||
div.style.display = "none"; | ||
} | ||
}; | ||
|
||
|
||
// openTrace opens the requested trace in a new window. | ||
function openTrace(traceID) { | ||
const urlParams = new URLSearchParams(window.location.search); | ||
const snapID = urlParams.get('snap'); | ||
window.open(`show-trace?snap=${snapID}&trace=${traceID}`, "_blank"); | ||
} | ||
|
||
var options = { | ||
valueNames: ['operation', 'startTime', 'relativeTime', 'goroutineID', 'spanID', 'stack', 'traceID'], | ||
item: function (values) { | ||
return ` | ||
<tr> | ||
<td> | ||
${values.operation} <a href="javascript:openTrace('${values.traceID}')">[+]</a> | ||
</td> | ||
<td> | ||
<div style="min-width:12em"> | ||
<span class="startTime"></span> | ||
<span class="relativeTime" style="float:right"></span> | ||
</div> | ||
</td>> | ||
<td style="text-align:center"> | ||
<div class="goroutineID link-button" onclick="toggleStackVisibility('${values.spanID}');"></div> | ||
<div style="display:none; text-align:left;" id="stack-${values.spanID}"><pre>${values.stack}</pre></div> | ||
</td> | ||
</tr>`; | ||
}, | ||
}; | ||
|
||
// Create the list of spans. | ||
var spansList = new List('spans-list', options, values); | ||
// Start with spans sorted newest first. | ||
spansList.sort('startTimeMicros', {order: "desc"}); | ||
|
||
</script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright 2021 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
package ui | ||
|
||
import ( | ||
"embed" | ||
"io/fs" | ||
) | ||
|
||
// This file deals with embedding assets used by /debug/tracez. | ||
|
||
//go:embed node_modules/list.js/dist/list.min.js | ||
var listJS embed.FS | ||
|
||
//go:embed templates/tracing/html_template.html | ||
// SpansTableTemplateSrc contains a template used by /debug/tracez | ||
var SpansTableTemplateSrc string | ||
|
||
// ListJS exposes list.js package | ||
var ListJS fs.FS | ||
|
||
func init() { | ||
f, err := fs.Sub(listJS, "node_modules/list.js/dist") | ||
if err != nil { | ||
panic(err) | ||
} | ||
ListJS = f | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.