Skip to content

Commit 81c39b0

Browse files
committed
Add support for typed internal pprof transfers
1 parent 3b1c0ba commit 81c39b0

File tree

16 files changed

+455
-150
lines changed

16 files changed

+455
-150
lines changed

api/gen/proto/go/query/v1/query.pb.go

Lines changed: 205 additions & 128 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/gen/proto/go/query/v1/query_vtproto.pb.go

Lines changed: 122 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/openapiv2/gen/phlare.swagger.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,14 @@
16621662
}
16631663
}
16641664
},
1665+
"v1PprofOutputMode": {
1666+
"type": "string",
1667+
"enum": [
1668+
"PPROF_BYTES",
1669+
"PPROF_TYPED"
1670+
],
1671+
"default": "PPROF_BYTES"
1672+
},
16651673
"v1PprofQuery": {
16661674
"type": "object",
16671675
"properties": {
@@ -1670,7 +1678,10 @@
16701678
"format": "int64"
16711679
},
16721680
"stackTraceSelector": {
1673-
"$ref": "#/definitions/v1StackTraceSelector",
1681+
"$ref": "#/definitions/v1StackTraceSelector"
1682+
},
1683+
"outputMode": {
1684+
"$ref": "#/definitions/v1PprofOutputMode",
16741685
"description": "TODO(kolesnikovae): Go PGO options."
16751686
}
16761687
}
@@ -1684,6 +1695,9 @@
16841695
"pprof": {
16851696
"type": "string",
16861697
"format": "byte"
1698+
},
1699+
"typedPprof": {
1700+
"$ref": "#/definitions/googlev1Profile"
16871701
}
16881702
}
16891703
},

api/query/v1/query.proto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,16 @@ message PprofQuery {
182182
int64 max_nodes = 1;
183183
optional types.v1.StackTraceSelector stack_trace_selector = 2;
184184
// TODO(kolesnikovae): Go PGO options.
185+
PprofOutputMode output_mode = 3;
186+
}
187+
188+
enum PprofOutputMode {
189+
PPROF_BYTES = 0;
190+
PPROF_TYPED = 1;
185191
}
186192

187193
message PprofReport {
188194
PprofQuery query = 1;
189195
bytes pprof = 2;
196+
google.v1.Profile typed_pprof = 3;
190197
}

cmd/pyroscope/help-all.txt.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,8 @@ Usage of ./pyroscope:
573573
Timeout for ingester client healthcheck RPCs. (default 5s)
574574
-querier.id string
575575
Querier ID, sent to the query-frontend to identify requests from the same querier. Defaults to hostname.
576+
-querier.internal-pprof-output-mode string
577+
The output mode for pprof queries, for transfers between internal components. Valid values are 'bytes' and 'typed'. (default "bytes")
576578
-querier.max-concurrent int
577579
The maximum number of concurrent queries allowed. (default 4)
578580
-querier.max-flamegraph-nodes-default int

cmd/pyroscope/help.txt.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ Usage of ./pyroscope:
157157
Run a health check on each ingester client during periodic cleanup. (default true)
158158
-querier.health-check-timeout duration
159159
Timeout for ingester client healthcheck RPCs. (default 5s)
160+
-querier.internal-pprof-output-mode string
161+
The output mode for pprof queries, for transfers between internal components. Valid values are 'bytes' and 'typed'. (default "bytes")
160162
-querier.max-flamegraph-nodes-default int
161163
Maximum number of flame graph nodes by default. 0 to disable. (default 8192)
162164
-querier.max-flamegraph-nodes-max int

docs/sources/configure-server/reference-configuration-parameters/index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,11 @@ distributor_usage_groups:
23162316
# CLI flag: -querier.sanitize-on-merge
23172317
[query_sanitize_on_merge: <boolean> | default = true]
23182318
2319+
# The output mode for pprof queries, for transfers between internal components.
2320+
# Valid values are 'bytes' and 'typed'.
2321+
# CLI flag: -querier.internal-pprof-output-mode
2322+
[query_internal_pprof_output_mode: <string> | default = "bytes"]
2323+
23192324
# Delete blocks containing samples older than the specified retention period. 0
23202325
# to disable.
23212326
# CLI flag: -compactor.blocks-retention-period

pkg/frontend/frontend.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ type Limits interface {
114114
QueryAnalysisEnabled(string) bool
115115
SymbolizerEnabled(string) bool
116116
QuerySanitizeOnMerge(string) bool
117+
QueryInternalPprofOutputMode(string) string
117118
validation.FlameGraphLimits
118119
}
119120

pkg/frontend/frontend_diff_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ func (m *mockLimits) QuerySanitizeOnMerge(_ string) bool {
2727
return true
2828
}
2929

30+
func (m *mockLimits) QueryInternalPprofOutputMode(_ string) string {
31+
return "bytes"
32+
}
33+
3034
func (m *mockLimits) MaxQueryParallelism(_ string) int {
3135
return 100
3236
}

pkg/frontend/readpath/queryfrontend/query_frontend.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ func (q *QueryFrontend) Query(
108108
if shouldSymbolize && originalQuery.QueryType == queryv1.QueryType_QUERY_TREE {
109109
modifiedQueries[i].QueryType = queryv1.QueryType_QUERY_PPROF
110110
modifiedQueries[i].Pprof = &queryv1.PprofQuery{
111-
MaxNodes: 0,
111+
MaxNodes: 0,
112+
OutputMode: queryv1.PprofOutputMode_PPROF_BYTES,
112113
}
113114
modifiedQueries[i].Tree = nil
114115
}
@@ -239,12 +240,17 @@ func (q *QueryFrontend) processAndSymbolizeProfiles(
239240
}
240241

241242
var prof googlev1.Profile
242-
if err := pprof.Unmarshal(r.Pprof.Pprof, &prof); err != nil {
243-
return fmt.Errorf("failed to unmarshal profile: %w", err)
244-
}
245-
246-
if err := q.symbolizer.SymbolizePprof(ctx, &prof); err != nil {
247-
return fmt.Errorf("failed to symbolize profile: %w", err)
243+
if r.Pprof.TypedPprof != nil {
244+
if err := q.symbolizer.SymbolizePprof(ctx, r.Pprof.TypedPprof); err != nil {
245+
return fmt.Errorf("failed to symbolize profile: %w", err)
246+
}
247+
} else {
248+
if err := pprof.Unmarshal(r.Pprof.Pprof, &prof); err != nil {
249+
return fmt.Errorf("failed to unmarshal profile: %w", err)
250+
}
251+
if err := q.symbolizer.SymbolizePprof(ctx, &prof); err != nil {
252+
return fmt.Errorf("failed to symbolize profile: %w", err)
253+
}
248254
}
249255

250256
// Convert back to tree if originally a tree
@@ -256,7 +262,7 @@ func (q *QueryFrontend) processAndSymbolizeProfiles(
256262
r.Tree = &queryv1.TreeReport{Tree: treeBytes}
257263
r.ReportType = queryv1.ReportType_REPORT_TREE
258264
r.Pprof = nil
259-
} else {
265+
} else if len(prof.Sample) > 0 {
260266
symbolizedBytes, err := pprof.Marshal(&prof, true)
261267
if err != nil {
262268
return fmt.Errorf("failed to marshal symbolized profile: %w", err)

0 commit comments

Comments
 (0)