Skip to content

Commit 6a63169

Browse files
committed
feat(pprof): apply all provider settings
Previously reportGlob, binaryGlob, and all TopOptions were ignored even if set in settings.json.
1 parent 9cc629a commit 6a63169

File tree

3 files changed

+70
-14
lines changed

3 files changed

+70
-14
lines changed

provider/pprof/index.ts

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,55 @@ import type {
77
MetaParams,
88
MetaResult,
99
Provider,
10-
ProviderSettings,
1110
} from '@openctx/provider'
1211
import { parseGolang } from './parser.js'
13-
import { type Node, findReportPath as findPprofSources, getPprof } from './pprof.js'
12+
import { type Node, type TopOptions, findReportPath as findPprofSources, getPprof } from './pprof.js'
13+
14+
interface Settings {
15+
/**
16+
* Glob pattern to match the profile report.
17+
*
18+
* Note, that forward slashes _do not need_ to be escaped in the patterns provided in `settings.json`
19+
*
20+
* @default "**\/*.pprof"
21+
* @example "**\/cmd\/*.pb.gz" (limit to asubdirectory)
22+
*/
23+
reportGlob?: string
24+
25+
/**
26+
* Glob pattern to match the Go binary from which the report was generated.
27+
*
28+
* By default `binaryGlob` not set. The provider will try to locate it by searching
29+
* for an executable file whose name matches that of its parent directory.
30+
* This is what a binary produces by `go build .` would be conventionally named.
31+
*/
32+
binaryGlob?: string
33+
34+
/**
35+
* The provider will not traverse the file tree past the directory containing `rootDirectoryMarkers`,
36+
* when searching for the profile report and the binary.
37+
*
38+
* @default [".git", "go.mod"]
39+
*/
40+
rootDirectoryMarkers?: string[]
41+
42+
/**
43+
* Options to control `pprof -top` output.
44+
*
45+
* @default top: { excludeInline: true, sort: 'cum' }
46+
* @example top: { excludeInline: false, sort: 'flat', nodeCount: 10 }
47+
*/
48+
top?: Pick<TopOptions, 'excludeInline' | 'nodeCount' | 'sort'>
49+
}
1450

1551
/**
1652
* An [OpenCtx](https://openctx.org) provider that annotates every function declaration with
1753
* the CPU time and memory allocations associated with it.
54+
*
55+
* Only Go files are supported.
1856
*/
19-
const pprof: Provider = {
20-
meta(params: MetaParams, settings: ProviderSettings): MetaResult {
57+
const pprof: Provider<Settings> = {
58+
meta(params: MetaParams, settings: Settings): MetaResult {
2159
return {
2260
name: 'pprof',
2361
annotations: {
@@ -26,7 +64,7 @@ const pprof: Provider = {
2664
}
2765
},
2866

29-
annotations(params: AnnotationsParams, settings: ProviderSettings): AnnotationsResult {
67+
annotations(params: AnnotationsParams, settings: Settings): AnnotationsResult {
3068
// Test files do not need pprof annotations.
3169
if (params.uri.endsWith('_test.go')) {
3270
return []
@@ -40,8 +78,9 @@ const pprof: Provider = {
4078

4179
const searchDir = dirname(params.uri).replace(/^file:\/{2}/, '')
4280
const sources = findPprofSources(searchDir, {
43-
reportGlob: (settings.reportGlob as string) || '**/*.pb.gz',
44-
rootDirectoryMarkers: settings.rootDirectoryMarkers as string[],
81+
reportGlob: settings.reportGlob || '**/*.pprof',
82+
rootDirectoryMarkers: settings.rootDirectoryMarkers || ['.git', 'go.mod'],
83+
binaryGlob: settings.binaryGlob,
4584
// TODO: pass workspaceRoot once it's made available
4685
// workspaceRoot: workspaceRoot,
4786
})
@@ -55,7 +94,7 @@ const pprof: Provider = {
5594
return []
5695
}
5796

58-
const top = pprof.top({ package: content.package })
97+
const top = pprof.top({ ...settings.top, package: content.package })
5998
if (top === null) {
6099
return []
61100
}
@@ -68,7 +107,9 @@ const pprof: Provider = {
68107
}
69108

70109
let item: Item = {
71-
title: `pprof ${top.type}: ${node.cum}${top.unit}, ${node.cumPerc}% (#${i + 1}, cum)`,
110+
title: `pprof ${top.type}: cum ${node.cum}${top.unit}, ${node.cumPerc}% (#${
111+
i + 1
112+
}, sort=${settings.top?.sort || 'cum'})`,
72113
}
73114

74115
const list = pprof.list(node.function)

provider/pprof/pprof.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ describe('pprof', () => {
158158
opts: { package: 'main', excludeInline: false },
159159
want: `go tool pprof -top -show="main\\." -cum report.pprof`,
160160
},
161+
{
162+
name: 'limit node count',
163+
tool: 'go tool pprof',
164+
opts: { package: 'main', nodeCount: 2 },
165+
want: `go tool pprof -top -show="main\\." -cum -noinlines -nodecount=2 report.pprof`,
166+
},
161167
])('top command ($name)', (tt: TopCmdTest) => {
162168
execSyncMock.mockReturnValueOnce(buffer(''))
163169
const pprof = new Pprof(tt.tool)

provider/pprof/pprof.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ export interface Node {
183183
}
184184

185185
export interface ListOutput {
186+
/** Raw output of `pprof -list`. */
186187
raw: string
187188
}
188189

@@ -229,14 +230,22 @@ export class Pprof {
229230

230231
private topCmd(options: TopOptions): string {
231232
const { report, binary } = this.sources
233+
const opt: TopOptions = {
234+
...options,
235+
sort: options.sort ?? 'cum',
236+
excludeInline: options.excludeInline ?? true,
237+
}
232238

233-
let cmd = this.tool + ` -top -show="${options.package}\\."`
234-
cmd += options.sort ? ` -${options.sort}` : ' -cum'
239+
let cmd = this.tool + ` -top -show="${options.package}\\." -${opt.sort}`
235240

236-
if (options.excludeInline === undefined || options.excludeInline === true) {
241+
if (opt.excludeInline) {
237242
cmd += ' -noinlines'
238243
}
239244

245+
if (options.nodeCount) {
246+
cmd += ` -nodecount=${options.nodeCount}`
247+
}
248+
240249
// Standalone `pprof` is not able to parse a Go binary, so it ignores it altogether.
241250
// Should we omit it from the command in case this.tool === 'pprof' ?
242251
if (binary) {
@@ -284,9 +293,9 @@ export class Pprof {
284293
}
285294

286295
return {
287-
type: reportType ? reportType[1] || 'cpu' : '',
296+
type: reportType ? reportType[1] ?? 'cpu' : '',
288297
file: binaryName ? binaryName[1] : undefined,
289-
unit: unit || 's',
298+
unit: unit ?? 's',
290299
nodes: nodes,
291300
}
292301
}

0 commit comments

Comments
 (0)