/
debug.go
107 lines (98 loc) · 2.66 KB
/
debug.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package utilroutes
import (
"bytes"
"runtime/pprof"
"sort"
"text/template"
)
func debugIndex() []byte {
profiles := pprof.Profiles()
sort.Slice(profiles, func(i, j int) bool {
var orderI, orderJ = 99, 99
for order, v := range []string{
"heap", "allocs", "goroutine", "threadcreate", "block", "mutex",
} {
switch v {
case profiles[i].Name():
orderI = order
case profiles[j].Name():
orderJ = order
}
}
return orderI < orderJ
})
var buf bytes.Buffer
if err := debugIndexTmpl.Execute(&buf, struct {
Instance string
ReqCount int
Profiles []*pprof.Profile
Descs map[string]string
}{
Instance: instanceName,
ReqCount: requests.Count(),
Profiles: profiles,
Descs: pprofDescs,
}); err != nil {
return []byte(err.Error())
}
return buf.Bytes()
}
var debugIndexTmpl = template.Must(template.New(``).Parse(`
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<base target="_blank">
<title>debug</title>
<style>
table { border-collapse: collapse; }
th,td { padding: 5px 10px; border: 1px dashed gray; }
</style>
</head>
<body>
<h3>{{ .Instance }}</h3>
<table>
<tr>
<th>Name</th>
<th>Count</th>
<th>Description</th>
</tr>
<tr>
<td><a href=./_debug/reqs>requests</a></td>
<td align=right>{{ .ReqCount }}</td>
<td>Requests in processing.</td>
</tr>
<tr>
<td><a href=./_debug/cpu>cpu</a></td>
<td></td>
<td> CPU profile. You can specify the duration in the "seconds" GET parameter. After you get the profile file, use the "go tool pprof" command to investigate the profile. </td>
</tr>
{{range .Profiles}}
<tr>
<td><a href="./_debug/{{.Name}}?debug=1">{{.Name}}</a></td>
<td align=right>{{.Count}}</td>
<td>{{ index $.Descs .Name }}</td>
</tr>
{{end}}
<tr>
<td><a href=./_debug/trace>trace</a></td>
<td></td>
<td> A trace of execution of the current program. You can specify the duration in the "seconds" GET parameter. After you get the trace file, use the "go tool trace" command to investigate the trace. </td>
</tr>
<tr>
<td><a href=./caches>pgcache</a></td>
<td></td>
<td> PostgreSQL caches if present. </td>
</tr>
</table>
</body>
</html>
`))
var pprofDescs = map[string]string{
"heap": "Heap memory profile. You can specify the gc GET parameter to run GC before taking the heap sample.",
"allocs": "Heap memory allocations, including all past.",
"goroutine": "Stack traces of all current goroutines.",
"threadcreate": "Stack traces that led to the creation of new OS threads.",
"block": "Stack traces that led to blocking on synchronization primitives.",
"mutex": "Stack traces of holders of contended mutexes.",
}