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, workdir, agent string) context.Context
- type BuildInfo
- 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) MonitorMemory(ctx context.Context)
- 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) 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 )
const Version = "v0.11.0"
Version is a manually-updated mechanism for tracking versions.
Variables ¶
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.events { list-style-type: none; } </style> {{block "head" .}}{{end}} </head> <body> <a href="/">Main</a> <a href="/info">Info</a> <a href="/memory">Memory</a> <a href="/metrics">Metrics</a> <a href="/rpc">RPC</a> <a href="/trace">Trace</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}} {{define "viewlink"}}<a href="/view/{{.}}">View {{.}}</a>{{end}} {{define "filelink"}}<a href="/file/{{.Session}}/{{.FileIdentity.Hash}}">{{.FileIdentity.URI}}</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 }, "options": func(s *cache.Session) []sessionOption { return showOptions(s.Options()) }, })
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>Per-package usage - not accurate, for guidance only</h2>
{{.PackageStats true}}
{{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>
<h2>Diagnostics</h2>
{{/*Service: []protocol.Server; each server has map[uri]fileReports;
each fileReport: map[diagnosticSoure]diagnosticReport
diagnosticSource is one of 5 source
diagnosticReport: snapshotID and map[hash]*source.Diagnostic
sourceDiagnostic: struct {
Range protocol.Range
Message string
Source string
Code string
CodeHref string
Severity protocol.DiagnosticSeverity
Tags []protocol.DiagnosticTag
Related []RelatedInformation
}
RelatedInformation: struct {
URI span.URI
Range protocol.Range
Message string
}
*/}}
<ul>{{range $k, $v := .Service.Diagnostics}}<li>{{$k}}:<ol>{{range $v}}<li>{{.}}</li>{{end}}</ol></li>{{end}}</ul>
{{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 {{.FileIdentity.Hash}}{{end}}
{{define "body"}}
{{with .}}
From: <b>{{template "sessionlink" .Session}}</b><br>
URI: <b>{{.URI}}</b><br>
Identifier: <b>{{.FileIdentity.Hash}}</b><br>
Version: <b>{{.Version}}</b><br>
Kind: <b>{{.Kind}}</b><br>
{{end}}
<h3>Contents</h3>
<pre>{{fcontent .Read}}</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>Views</h2>
<ul>{{range .State.Views}}<li>{{.Name}} is {{template "viewlink" .ID}} from {{template "sessionlink" .Session.ID}} in {{.Folder}}</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"}}
<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}}<li>{{.Name}} is {{template "viewlink" .ID}} in {{.Folder}}</li>{{end}}</ul>
<h2>Overlays</h2>
<ul>{{range .Overlays}}<li>{{template "filelink" .}}</li>{{end}}</ul>
<h2>Options</h2>
{{range options .}}
<p><b>{{.Name}}</b> {{.Type}}</p>
<p><i>default:</i> {{.Default}}</p>
{{if ne .Default .Current}}<p><i>current:</i> {{.Current}}</p>{{end}}
{{end}}
{{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>{{template "details" .Selected.Last}}</ul>{{end}}
{{if .Selected.Longest}}<H3>Longest</H3><ul>{{template "details" .Selected.Longest}}</ul>{{end}}
{{end}}
{{end}}
{{define "details"}}
<li>{{.Offset}} {{.Name}} {{.Duration}} {{.Tags}}</li>
{{if .Events}}<ul class=events>{{range .Events}}<li>{{.Offset}} {{.Tags}}</li>{{end}}</ul>{{end}}
{{if .Children}}<ul>{{range .Children}}{{template "details" .}}{{end}}</ul>{{end}}
{{end}}
`))
var ViewTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}View {{.ID}}{{end}}
{{define "body"}}
Name: <b>{{.Name}}</b><br>
Folder: <b>{{.Folder}}</b><br>
<h2>Environment</h2>
<ul>{{range .Options.Env}}<li>{{.}}</li>{{end}}</ul>
{{end}}
`))
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 Workdir 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) MonitorMemory ¶
MonitorMemory starts recording memory statistics each second.
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.
type TraceResults ¶
type TraceResults struct { Traces []*traceSet Selected *traceSet }