Documentation ¶
Overview ¶
Package debug exports debug information for gopls.
Index ¶
- Constants
- Variables
- func PrintVersionInfo(_ context.Context, w io.Writer, verbose bool, mode PrintMode) error
- func StdTrace(exporter event.Exporter) event.Exporter
- func WithInstance(ctx context.Context, agent string) context.Context
- type Client
- type Instance
- func (i *Instance) AddService(s protocol.Server, session *cache.Session)
- func (i *Instance) DebugAddress() string
- func (i *Instance) ListenedDebugAddress() string
- func (i *Instance) PrintServerInfo(ctx context.Context, w io.Writer)
- func (i *Instance) Serve(ctx context.Context, addr string) (string, error)
- func (i *Instance) SetLogFile(logfile string, isDaemon bool) (func(), error)
- type PrintMode
- type Rpcs
- type Server
- type ServerVersion
- type State
- func (st *State) Analysis() (_ analysisTmpl)
- func (st *State) Bugs() []bug.Bug
- func (st *State) Cache(id string) *cache.Cache
- func (st *State) Caches() []*cache.Cache
- func (st *State) Client(id string) *Client
- func (st *State) Clients() []*Client
- func (st *State) Servers() []*Server
- func (st *State) Session(id string) *cache.Session
- func (st *State) Sessions() []*cache.Session
- func (st *State) View(id string) *cache.View
- func (st *State) Views() []*cache.View
- type TraceResults
Constants ¶
const ( PlainText = PrintMode(iota) Markdown HTML JSON )
Variables ¶
var AnalysisTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Analysis{{end}}
{{define "body"}}
<h2>Analyzer.Run times</h2>
<ul>{{range .AnalyzerRunTimes}}<li>{{.Duration}} {{.Label}}</li>{{end}}</ul>
{{end}}
`))
var BaseTemplate = template.Must(template.New("").Parse(` <html> <head> <title>{{template "title" .}}</title> <style> .profile-name{ display:inline-block; width:6rem; } td.value { text-align: right; } ul.spans { font-family: monospace; font-size: 85%; } body { font-family: sans-serif; font-size: 1rem; line-height: normal; } </style> {{block "head" .}}{{end}} </head> <body> <a href="/">Main</a> <a href="/info">Info</a> <a href="/memory">Memory</a> <a href="/debug/pprof">Profiling</a> <a href="/metrics">Metrics</a> <a href="/rpc">RPC</a> <a href="/trace">Trace</a> <a href="/analysis">Analysis</a> <hr> <h1>{{template "title" .}}</h1> {{block "body" .}} Unknown page {{end}} </body> </html> {{define "cachelink"}}<a href="/cache/{{.}}">Cache {{.}}</a>{{end}} {{define "clientlink"}}<a href="/client/{{.}}">Client {{.}}</a>{{end}} {{define "serverlink"}}<a href="/server/{{.}}">Server {{.}}</a>{{end}} {{define "sessionlink"}}<a href="/session/{{.}}">Session {{.}}</a>{{end}} `)).Funcs(template.FuncMap{ "fuint64": fuint64, "fuint32": fuint32, "fcontent": fcontent, "localAddress": func(s string) string { host, port, err := net.SplitHostPort(s) if err != nil { return s } ip := net.ParseIP(host) if ip == nil { return s } if ip.IsLoopback() || ip.IsUnspecified() { return "localhost:" + port } return s }, })
var CacheTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Cache {{.ID}}{{end}}
{{define "body"}}
<h2>memoize.Store entries</h2>
<ul>{{range $k,$v := .MemStats}}<li>{{$k}} - {{$v}}</li>{{end}}</ul>
<h2>File stats</h2>
<p>
{{- $stats := .FileStats -}}
Total: <b>{{$stats.Total}}</b><br>
Largest: <b>{{$stats.Largest}}</b><br>
Errors: <b>{{$stats.Errs}}</b><br>
</p>
{{end}}
`))
var ClientTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Client {{.Session.ID}}{{end}}
{{define "body"}}
Using session: <b>{{template "sessionlink" .Session.ID}}</b><br>
{{if .DebugAddress}}Debug this client at: <a href="http://{{localAddress .DebugAddress}}">{{localAddress .DebugAddress}}</a><br>{{end}}
Logfile: {{.Logfile}}<br>
Gopls Path: {{.GoplsPath}}<br>
{{end}}
`))
var DebugTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}GoPls Debug pages{{end}}
{{define "body"}}
<a href="/debug/pprof">Profiling</a>
{{end}}
`))
var FileTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Overlay {{.Identity.Hash}}{{end}}
{{define "body"}}
{{with .}}
URI: <b>{{.URI}}</b><br>
Identifier: <b>{{.Identity.Hash}}</b><br>
Version: <b>{{.Version}}</b><br>
Kind: <b>{{.Kind}}</b><br>
{{end}}
<h3>Contents</h3>
<pre>{{fcontent .Content}}</pre>
{{end}}
`))
var InfoTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Gopls version information{{end}}
{{define "body"}}
{{.}}
{{end}}
`))
var MainTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Gopls server information{{end}}
{{define "body"}}
<h2>Caches</h2>
<ul>{{range .State.Caches}}<li>{{template "cachelink" .ID}}</li>{{end}}</ul>
<h2>Sessions</h2>
<ul>{{range .State.Sessions}}<li>{{template "sessionlink" .ID}} from {{template "cachelink" .Cache.ID}}</li>{{end}}</ul>
<h2>Clients</h2>
<ul>{{range .State.Clients}}<li>{{template "clientlink" .Session.ID}}</li>{{end}}</ul>
<h2>Servers</h2>
<ul>{{range .State.Servers}}<li>{{template "serverlink" .ID}}</li>{{end}}</ul>
<h2>Bug reports</h2>
<dl>{{range .State.Bugs}}<dt>{{.Key}}</dt><dd>{{.Description}}</dd>{{end}}</dl>
{{end}}
`))
var MemoryTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Gopls memory usage{{end}}
{{define "head"}}<meta http-equiv="refresh" content="5">{{end}}
{{define "body"}}
<form action="/gc"><input type="submit" value="Run garbage collector"/></form>
<h2>Stats</h2>
<table>
<tr><td class="label">Allocated bytes</td><td class="value">{{fuint64 .HeapAlloc}}</td></tr>
<tr><td class="label">Total allocated bytes</td><td class="value">{{fuint64 .TotalAlloc}}</td></tr>
<tr><td class="label">System bytes</td><td class="value">{{fuint64 .Sys}}</td></tr>
<tr><td class="label">Heap system bytes</td><td class="value">{{fuint64 .HeapSys}}</td></tr>
<tr><td class="label">Malloc calls</td><td class="value">{{fuint64 .Mallocs}}</td></tr>
<tr><td class="label">Frees</td><td class="value">{{fuint64 .Frees}}</td></tr>
<tr><td class="label">Idle heap bytes</td><td class="value">{{fuint64 .HeapIdle}}</td></tr>
<tr><td class="label">In use bytes</td><td class="value">{{fuint64 .HeapInuse}}</td></tr>
<tr><td class="label">Released to system bytes</td><td class="value">{{fuint64 .HeapReleased}}</td></tr>
<tr><td class="label">Heap object count</td><td class="value">{{fuint64 .HeapObjects}}</td></tr>
<tr><td class="label">Stack in use bytes</td><td class="value">{{fuint64 .StackInuse}}</td></tr>
<tr><td class="label">Stack from system bytes</td><td class="value">{{fuint64 .StackSys}}</td></tr>
<tr><td class="label">Bucket hash bytes</td><td class="value">{{fuint64 .BuckHashSys}}</td></tr>
<tr><td class="label">GC metadata bytes</td><td class="value">{{fuint64 .GCSys}}</td></tr>
<tr><td class="label">Off heap bytes</td><td class="value">{{fuint64 .OtherSys}}</td></tr>
</table>
<h2>By size</h2>
<table>
<tr><th>Size</th><th>Mallocs</th><th>Frees</th></tr>
{{range .BySize}}<tr><td class="value">{{fuint32 .Size}}</td><td class="value">{{fuint64 .Mallocs}}</td><td class="value">{{fuint64 .Frees}}</td></tr>{{end}}
</table>
{{end}}
`))
var RPCTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}RPC Information{{end}}
{{define "body"}}
<H2>Inbound</H2>
{{template "rpcSection" .Inbound}}
<H2>Outbound</H2>
{{template "rpcSection" .Outbound}}
{{end}}
{{define "rpcSection"}}
{{range .}}<P>
<b>{{.Method}}</b> {{.Started}} <a href="/trace/{{.Method}}">traces</a> ({{.InProgress}} in progress)
<br>
<i>Latency</i> {{with .Latency}}{{.Mean}} ({{.Min}}<{{.Max}}){{end}}
<i>By bucket</i> 0s {{range .Latency.Values}}{{if gt .Count 0}}<b>{{.Count}}</b> {{.Limit}} {{end}}{{end}}
<br>
<i>Received</i> {{.Received}} (avg. {{.ReceivedMean}})
<i>Sent</i> {{.Sent}} (avg. {{.SentMean}})
<br>
<i>Result codes</i> {{range .Codes}}{{.Key}}={{.Count}} {{end}}
</P>
{{end}}
{{end}}
`))
var ServerTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Server {{.ID}}{{end}}
{{define "body"}}
{{if .DebugAddress}}Debug this server at: <a href="http://{{localAddress .DebugAddress}}">{{localAddress .DebugAddress}}</a><br>{{end}}
Logfile: {{.Logfile}}<br>
Gopls Path: {{.GoplsPath}}<br>
{{end}}
`))
var SessionTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Session {{.ID}}{{end}}
{{define "body"}}
From: <b>{{template "cachelink" .Cache.ID}}</b><br>
<h2>Views</h2>
<ul>{{range .Views}}
{{- $envOverlay := .EnvOverlay -}}
<li>ID: <b>{{.ID}}</b><br>
Type: <b>{{.Type}}</b><br>
Root: <b>{{.Root}}</b><br>
{{- if $envOverlay}}
Env overlay: <b>{{$envOverlay}})</b><br>
{{end -}}
Folder: <b>{{.Folder.Name}}:{{.Folder.Dir}}</b></li>
{{end}}</ul>
<h2>Overlays</h2>
{{$session := .}}
<ul>{{range .Overlays}}
<li>
<a href="/file/{{$session.ID}}/{{.Identity.Hash}}">{{.Identity.URI}}</a>
</li>{{end}}</ul>
{{end}}
`))
var TraceTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Trace Information{{end}}
{{define "body"}}
{{range .Traces}}<a href="/trace/{{.Name}}">{{.Name}}</a> last: {{.Last.Duration}}, longest: {{.Longest.Duration}}<br>{{end}}
{{if .Selected}}
<H2>{{.Selected.Name}}</H2>
{{if .Selected.Last}}<H3>Last</H3><ul class='spans'>{{template "completeSpan" .Selected.Last}}</ul>{{end}}
{{if .Selected.Longest}}<H3>Longest</H3><ul class='spans'>{{template "completeSpan" .Selected.Longest}}</ul>{{end}}
{{end}}
<H2>Recent spans (oldest first)</H2>
<p>
A finite number of recent span start/end times are shown below.
The nesting represents the children of a parent span (and the log events within a span).
A span may appear twice: chronologically at toplevel, and nested within its parent.
</p>
<ul class='spans'>{{range .Recent}}{{template "spanStartEnd" .}}{{end}}</ul>
{{end}}
{{define "spanStartEnd"}}
{{if .Start}}
<li>{{.Span.Header .Start}}</li>
{{else}}
{{template "completeSpan" .Span}}
{{end}}
{{end}}
{{define "completeSpan"}}
<li>{{.Header false}}</li>
{{if .Events}}<ul>{{range .Events}}<li>{{.Header}}</li>{{end}}</ul>{{end}}
{{if .ChildStartEnd}}<ul>{{range .ChildStartEnd}}{{template "spanStartEnd" .}}{{end}}</ul>{{end}}
{{end}}
`))
TraceTmpl extends BaseTemplate and renders a TraceResults, e.g. from getData().
Functions ¶
func PrintVersionInfo ¶
PrintVersionInfo writes version information to w, using the output format specified by mode. verbose controls whether additional information is written, including section headers.
Types ¶
type Client ¶
type Client struct { Session *cache.Session DebugAddress string Logfile string GoplsPath string ServerID string Service protocol.Server }
A Client is an incoming connection from a remote client.
type Instance ¶
type Instance struct { Logfile string StartTime time.Time ServerAddress string OCAgentConfig string LogWriter io.Writer State *State // contains filtered or unexported fields }
An Instance holds all debug information associated with a gopls instance.
func GetInstance ¶
func (*Instance) AddService ¶
func (*Instance) DebugAddress ¶
func (*Instance) ListenedDebugAddress ¶
func (*Instance) PrintServerInfo ¶
PrintServerInfo writes HTML debug info to w for the Instance.
type Rpcs ¶
type Rpcs struct { Inbound []*rpcStats // stats for incoming lsp rpcs sorted by method name Outbound []*rpcStats // stats for outgoing lsp rpcs sorted by method name // contains filtered or unexported fields }
type Server ¶
type Server struct { ID string DebugAddress string Logfile string GoplsPath string ClientID string }
A Server is an outgoing connection to a remote LSP server.
type ServerVersion ¶
ServerVersion is the format used by gopls to report its version to the client. This format is structured so that the client can parse it easily.
func VersionInfo ¶
func VersionInfo() *ServerVersion
VersionInfo returns the build info for the gopls process. If it was not built in module mode, we return a GOPATH-specific message with the hardcoded version.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State holds debugging information related to the server state.
func (*State) Analysis ¶
func (st *State) Analysis() (_ analysisTmpl)
Analysis returns the global Analysis template value.
type TraceResults ¶
type TraceResults struct { Traces []*traceSet Selected *traceSet Recent []spanStartEnd }
A TraceResults is the subject for the /trace HTML template.