Skip to content

Commit 2395bd1

Browse files
zzzariescopybara-github
authored andcommitted
Support source code linkage given path prefix in launch command
example: `xprof --logdir=<logdir> --src_prefix=<prefixpath to repo>` PiperOrigin-RevId: 844977541
1 parent fc258cc commit 2395bd1

27 files changed

+226
-58
lines changed

frontend/app/common/interfaces/capture_profile.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@ export interface CaptureProfileOptions {
1616
pythonTracerLevel: number;
1717
delay: number;
1818
}
19+
20+
/** A serializable object with profiler configuration details. */
21+
export interface ProfilerConfig {
22+
hideCaptureProfileButton: boolean;
23+
srcPathPrefix: string;
24+
}

frontend/app/components/sidenav/sidenav.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {NavigationEvent} from 'org_xprof/frontend/app/common/interfaces/navigati
77
import {RunToolsMap} from 'org_xprof/frontend/app/common/interfaces/tool';
88
import {CommunicationService} from 'org_xprof/frontend/app/services/communication_service/communication_service';
99
import {DataServiceV2} from 'org_xprof/frontend/app/services/data_service_v2/data_service_v2';
10-
import {setCurrentRunAction, updateRunToolsMapAction} from 'org_xprof/frontend/app/store/actions';
10+
import {setCurrentRunAction, setProfilerConfigAction, updateRunToolsMapAction} from 'org_xprof/frontend/app/store/actions';
1111
import {getCurrentRun, getRunToolsMap} from 'org_xprof/frontend/app/store/selectors';
1212
import {firstValueFrom, Observable, ReplaySubject} from 'rxjs';
1313
import {takeUntil} from 'rxjs/operators';
@@ -171,6 +171,7 @@ export class SideNav implements OnInit, OnDestroy {
171171
const config = await firstValueFrom(
172172
this.dataService.getConfig().pipe(takeUntil(this.destroyed)));
173173
if (config) {
174+
this.store.dispatch(setProfilerConfigAction({config}));
174175
this.hideCaptureProfileButton = config.hideCaptureProfileButton;
175176
}
176177
}

frontend/app/components/source_mapper/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ xprof_ng_module(
2525
"@org_xprof//frontend/app/common/angular:angular_material_select",
2626
"@org_xprof//frontend/app/common/angular:angular_material_tooltip",
2727
"@org_xprof//frontend/app/common/constants",
28+
"@org_xprof//frontend/app/common/interfaces",
2829
"@org_xprof//frontend/app/components/stack_trace_snippet",
2930
"@org_xprof//frontend/app/components/stack_trace_snippet:message",
3031
"@org_xprof//frontend/app/services/data_service_v2:data_service_v2_interface",

frontend/app/components/source_mapper/source_mapper.ng.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
</mat-select>
1010
</mat-form-field>
1111
<stack-trace-snippet
12+
[srcPathPrefix]="srcPathPrefix"
1213
[sourceFileAndLineNumber]="adaptedSourceFileAndLineNumber"
1314
[stackTrace]="adaptedStackTrace"
1415
[sourceContextWindow]="sourceContextWindow"

frontend/app/components/source_mapper/source_mapper.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import {Component, inject, Input, OnChanges, OnDestroy, SimpleChanges} from '@an
22
import {Store} from '@ngrx/store';
33
import {GRAPH_TYPE_DEFAULT, GRAPH_TYPE_ORIGINAL_HLO} from 'org_xprof/frontend/app/common/constants/constants';
44
import {FileExtensionType} from 'org_xprof/frontend/app/common/constants/enums';
5+
import {ProfilerConfig} from 'org_xprof/frontend/app/common/interfaces/capture_profile';
56
import {DATA_SERVICE_INTERFACE_TOKEN, DataServiceV2Interface} from 'org_xprof/frontend/app/services/data_service_v2/data_service_v2_interface';
67
import {Address} from 'org_xprof/frontend/app/services/source_code_service/source_code_service_interface';
7-
import {getTagsState} from 'org_xprof/frontend/app/store/selectors';
8+
import {getProfilerConfig, getTagsState} from 'org_xprof/frontend/app/store/selectors';
89
import {ReplaySubject} from 'rxjs';
910
import {takeUntil} from 'rxjs/operators';
1011

@@ -63,6 +64,8 @@ export class SourceMapper implements OnDestroy, OnChanges {
6364
sourceFileNames: string[] = [];
6465
selectedSourceFileName = '';
6566
tags: string[] = [];
67+
// The prefix of the source file path if specified by users.
68+
srcPathPrefix = '';
6669

6770
constructor(private readonly store: Store<{}>) {
6871
this.store.select(getTagsState)
@@ -71,6 +74,12 @@ export class SourceMapper implements OnDestroy, OnChanges {
7174
if (!tags || tags.length === 0) return;
7275
this.tags = tags;
7376
});
77+
this.store.select(getProfilerConfig)
78+
.pipe(takeUntil(this.destroyed))
79+
.subscribe((config: ProfilerConfig) => {
80+
if (!config) return;
81+
this.srcPathPrefix = config.srcPathPrefix;
82+
});
7483
}
7584

7685
ngOnChanges(changes: SimpleChanges) {

frontend/app/components/stack_trace_snippet/stack_frame_snippet.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export class StackFrameSnippet implements OnChanges, OnDestroy {
2020
@Input() sourceCodeSnippetAddress: Address|undefined = undefined;
2121
@Input() topOfStack: boolean|undefined = undefined;
2222
@Input() usingSourceFileAndLineNumber: boolean|undefined = undefined;
23+
@Input() srcPathPrefix = '';
2324
private readonly route: ActivatedRoute = inject(ActivatedRoute);
2425
private readonly sourceCodeService: SourceCodeServiceInterface =
2526
inject(SOURCE_CODE_SERVICE_INTERFACE_TOKEN);
@@ -30,12 +31,15 @@ export class StackFrameSnippet implements OnChanges, OnDestroy {
3031
codeSearchLink: string|undefined = undefined;
3132
codeSearchLinkTooltip: string|undefined = undefined;
3233
lineNumberToMetricMap: Map<number, Metric>|undefined = undefined;
34+
isCodeFetchEnabled = false;
3335

3436
constructor() {
3537
this.route.params.pipe(takeUntil(this.destroy$)).subscribe((params) => {
36-
this.sessionId = (params || {})['sessionId'];
38+
this.sessionId = (params || {})['sessionId'] || (params || {})['run'] ||
39+
this.sessionId;
3740
this.reload();
3841
});
42+
this.isCodeFetchEnabled = this.sourceCodeService.isCodeFetchEnabled();
3943
}
4044

4145
ngOnDestroy(): void {
@@ -60,7 +64,8 @@ export class StackFrameSnippet implements OnChanges, OnDestroy {
6064
}
6165

6266
get loaded() {
63-
return this.frame !== undefined || this.failure !== undefined;
67+
return this.frame !== undefined || this.failure !== undefined ||
68+
!this.isCodeFetchEnabled;
6469
}
6570

6671
get isAtTopOfStack(): boolean {
@@ -111,7 +116,7 @@ export class StackFrameSnippet implements OnChanges, OnDestroy {
111116
this.sourceCodeService
112117
.codeSearchLink(
113118
this.sessionId, this.sourceCodeSnippetAddress.fileName,
114-
this.sourceCodeSnippetAddress.lineNumber)
119+
this.sourceCodeSnippetAddress.lineNumber, this.srcPathPrefix)
115120
.pipe(takeUntil(this.destroy$))
116121
.subscribe({
117122
next: (link) => {

frontend/app/components/stack_trace_snippet/stack_trace_snippet.ng.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
*ngFor="let addr of sourceCodeSnippetAddresses; let isFirst = first; trackBy: trackByIndex"
66
[sourceCodeSnippetAddress]="addr"
77
[topOfStack]="isFirst"
8-
[usingSourceFileAndLineNumber]="usingSourceFileAndLineNumber">
8+
[usingSourceFileAndLineNumber]="usingSourceFileAndLineNumber"
9+
[srcPathPrefix]="srcPathPrefix">
910
</stack-frame-snippet>
1011
</ng-container>
1112

frontend/app/components/stack_trace_snippet/stack_trace_snippet.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ export class StackTraceSnippet implements OnChanges {
3131
* The number of lines to show around the stack frame.
3232
*/
3333
@Input() sourceContextWindow = 40;
34+
/**
35+
* The prefix of the source file path.
36+
*
37+
* This is used to construct the src link given different repositories that
38+
* serves the source code.
39+
*/
40+
@Input() srcPathPrefix = '';
41+
3442
sourceCodeSnippetAddresses: readonly Address[] = [];
3543

3644
ngOnChanges(changes: SimpleChanges) {

frontend/app/services/data_service_v2/data_service_v2.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import {Injectable} from '@angular/core';
44
import {Store} from '@ngrx/store';
55
import {API_PREFIX, CAPTURE_PROFILE_API, CONFIG_API, DATA_API, GRAPH_TYPE_DEFAULT, GRAPHVIZ_PAN_ZOOM_CONTROL, HLO_MODULE_LIST_API, HOSTS_API, LOCAL_URL, PLUGIN_NAME, RUN_TOOLS_API, RUNS_API, USE_SAVED_RESULT} from 'org_xprof/frontend/app/common/constants/constants';
66
import {FileExtensionType} from 'org_xprof/frontend/app/common/constants/enums';
7-
import {CaptureProfileOptions, CaptureProfileResponse} from 'org_xprof/frontend/app/common/interfaces/capture_profile';
7+
import {CaptureProfileOptions, CaptureProfileResponse, ProfilerConfig, } from 'org_xprof/frontend/app/common/interfaces/capture_profile';
88
import {DataTable} from 'org_xprof/frontend/app/common/interfaces/data_table';
99
import {HostMetadata} from 'org_xprof/frontend/app/common/interfaces/hosts';
1010
import {type SmartSuggestionReport} from 'org_xprof/frontend/app/common/interfaces/smart_suggestion.jsonpb_decls';
1111
import * as utils from 'org_xprof/frontend/app/common/utils/utils';
1212
import {OpProfileData, OpProfileSummary} from 'org_xprof/frontend/app/components/op_profile/op_profile_data';
13-
import {DataServiceV2Interface, ProfilerConfig} from 'org_xprof/frontend/app/services/data_service_v2/data_service_v2_interface';
13+
import {DataServiceV2Interface} from 'org_xprof/frontend/app/services/data_service_v2/data_service_v2_interface';
1414
import {setErrorMessageStateAction} from 'org_xprof/frontend/app/store/actions';
1515
import {Observable, of} from 'rxjs';
1616
import {catchError} from 'rxjs/operators';
@@ -307,14 +307,17 @@ export class DataServiceV2 implements DataServiceV2Interface {
307307
// Host is not specified for hlo text view now, as we assume metadata the
308308
// same across all hosts.
309309
const host = '';
310-
const params = this.getHttpParams('', '')
311-
.set('run', sessionId)
312-
.set('tag', tool)
313-
.set('host', host)
314-
.set('graph_type', graphType)
315-
.set('module_name', moduleName)
316-
.set('type', type)
317-
.set('show_metadata', String(showMetadata));
310+
let params = this.getHttpParams('', '')
311+
.set('run', sessionId)
312+
.set('tag', tool)
313+
.set('host', host)
314+
.set('graph_type', graphType)
315+
.set('module_name', moduleName)
316+
.set('type', type)
317+
.set('show_metadata', String(showMetadata));
318+
if (programId) {
319+
params = params.set('program_id', String(programId));
320+
}
318321
return this.get(this.pathPrefix + DATA_API, {
319322
'params': params,
320323
'responseType': responseType,

frontend/app/services/data_service_v2/data_service_v2_interface.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,13 @@
44
*/
55

66
import {InjectionToken} from '@angular/core';
7+
import {ProfilerConfig} from 'org_xprof/frontend/app/common/interfaces/capture_profile';
78
import {DataTable} from 'org_xprof/frontend/app/common/interfaces/data_table';
89
import {GraphTypeObject} from 'org_xprof/frontend/app/common/interfaces/graph_viewer';
910
import {HostMetadata} from 'org_xprof/frontend/app/common/interfaces/hosts';
11+
import {type SmartSuggestionReport} from 'org_xprof/frontend/app/common/interfaces/smart_suggestion.jsonpb_decls';
1012
import {OpProfileData, OpProfileSummary} from 'org_xprof/frontend/app/components/op_profile/op_profile_data';
1113
import {Observable} from 'rxjs';
12-
import {type SmartSuggestionReport} from 'org_xprof/frontend/app/common/interfaces/smart_suggestion.jsonpb_decls';
13-
14-
/** A serializable object with profiler configuration details. */
15-
export interface ProfilerConfig {
16-
hideCaptureProfileButton: boolean;
17-
}
1814

1915
/** The data service class that calls API and return response. */
2016
export interface DataServiceV2Interface {

0 commit comments

Comments
 (0)