Skip to content

Commit bfcbb87

Browse files
authored
Initial work to enable and see tracing data for specific jobs (#54)
* Initial work to enable and see tracing data for specific jobs * Support for opening a file trace
1 parent 21e6506 commit bfcbb87

File tree

4 files changed

+104
-13
lines changed

4 files changed

+104
-13
lines changed

package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,16 @@
295295
"category": "Db2 for i",
296296
"icon": "$(info)"
297297
},
298+
{
299+
"command": "vscode-db2i.jobManager.enableTracing",
300+
"title": "Enable Tracing",
301+
"category": "Db2 for i"
302+
},
303+
{
304+
"command": "vscode-db2i.jobManager.getTrace",
305+
"title": "Get Trace Data",
306+
"category": "Db2 for i"
307+
},
298308
{
299309
"command": "vscode-db2i.jobManager.newConfig",
300310
"title": "Save settings to config",
@@ -336,6 +346,14 @@
336346
"command": "vscode-db2i.jobManager.viewJobLog",
337347
"when": "never"
338348
},
349+
{
350+
"command": "vscode-db2i.jobManager.enableTracing",
351+
"when": "never"
352+
},
353+
{
354+
"command": "vscode-db2i.jobManager.getTrace",
355+
"when": "never"
356+
},
339357
{
340358
"command": "vscode-db2i.jobManager.newConfig",
341359
"when": "never"
@@ -496,6 +514,16 @@
496514
"when": "view == jobManager && viewItem == sqlJob",
497515
"group": "inline"
498516
},
517+
{
518+
"command": "vscode-db2i.jobManager.enableTracing",
519+
"when": "view == jobManager && viewItem == sqlJob",
520+
"group": "trace@1"
521+
},
522+
{
523+
"command": "vscode-db2i.jobManager.getTrace",
524+
"when": "view == jobManager && viewItem == sqlJob",
525+
"group": "trace@2"
526+
},
499527
{
500528
"command": "vscode-db2i.jobManager.newConfig",
501529
"when": "view == jobManager && viewItem == sqlJob",

src/connection/serverComponent.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ export class ServerComponent {
3535
return this.outputChannel;
3636
}
3737

38-
static writeOutput(jsonString: string) {
38+
static writeOutput(jsonString: string, show = false) {
39+
if (show) {
40+
this.outputChannel.show();
41+
}
42+
3943
if (this.outputChannel) {
4044
this.outputChannel.appendLine(jsonString);
4145
}

src/connection/sqlJob.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export class SQLJob {
3434
private channel: any;
3535
private responseEmitter: EventEmitter = new EventEmitter();
3636
private status: JobStatus = JobStatus.NotStarted;
37+
38+
private traceFile: string|undefined;
3739
private isTracingChannelData: boolean = false;
3840

3941
id: string | undefined;
@@ -153,6 +155,11 @@ export class SQLJob {
153155

154156
return version;
155157
}
158+
159+
getTraceFilePath(): string|undefined {
160+
return this.traceFile;
161+
}
162+
156163
async getTraceData(): Promise<GetTraceDataResult> {
157164
const tracedataReqObj = {
158165
id: SQLJob.getNewUniqueRequestId(),
@@ -166,16 +173,19 @@ export class SQLJob {
166173
if (rpy.success !== true) {
167174
throw new Error(rpy.error || `Failed to get trace data from backend`);
168175
}
176+
169177
return rpy;
170178
}
171-
//TODO: add/modify this API to allow manipulation of JTOpen tracing, and add tests
179+
172180
async setTraceConfig(dest: ServerTraceDest, level: ServerTraceLevel): Promise<SetConfigResult> {
173181
const reqObj = {
174182
id: SQLJob.getNewUniqueRequestId(),
175183
type: `setconfig`,
176184
tracedest: dest,
177185
tracelevel: level
178186
};
187+
188+
this.isTracingChannelData = true;
179189

180190
const result = await this.send(JSON.stringify(reqObj));
181191

@@ -184,6 +194,9 @@ export class SQLJob {
184194
if (rpy.success !== true) {
185195
throw new Error(rpy.error || `Failed to set trace options on backend`);
186196
}
197+
198+
this.traceFile = (rpy.tracedest && rpy.tracedest[0] === `/` ? rpy.tracedest : undefined);
199+
187200
return rpy;
188201
}
189202

src/views/jobManager/jobManagerView.ts

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import vscode, { MarkdownString, ProgressLocation, ThemeIcon, TreeItem, TreeItemCollapsibleState, commands, env, window, workspace } from "vscode";
1+
import vscode, { MarkdownString, ProgressLocation, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri, commands, env, window, workspace } from "vscode";
22
import { TreeDataProvider } from "vscode";
33
import { Config, JobManager } from "../../config";
4-
import { JobInfo } from "../../connection/manager";
4+
import { JobInfo, SQLJobManager } from "../../connection/manager";
55
import { editJobUi } from "./editJob";
66
import { displayJobLog } from "./jobLog";
7+
import { ServerTraceDest, ServerTraceLevel } from "../../connection/types";
8+
import { ServerComponent } from "../../connection/serverComponent";
79
import { updateStatusBar } from "./statusBar";
810
import { TransactionEndType } from "../../connection/sqlJob";
911
import { ConfigGroup, ConfigManager } from "./ConfigManager";
@@ -24,9 +26,9 @@ export class JobManagerView implements TreeDataProvider<any> {
2426
...ConfigManager.initialiseSaveCommands(),
2527

2628
vscode.commands.registerCommand(`vscode-db2i.jobManager.newJob`, async () => {
27-
await window.withProgress({location: ProgressLocation.Window}, async (progress) => {
29+
await window.withProgress({ location: ProgressLocation.Window }, async (progress) => {
2830
try {
29-
progress.report({message: `Spinning up SQL job...`});
31+
progress.report({ message: `Spinning up SQL job...` });
3032
await JobManager.newJob();
3133
} catch (e) {
3234
window.showErrorMessage(e.message);
@@ -103,15 +105,15 @@ export class JobManagerView implements TreeDataProvider<any> {
103105
if (selected) {
104106
editJobUi(selected.job.options, selected.name).then(newOptions => {
105107
if (newOptions) {
106-
window.withProgress({location: ProgressLocation.Window}, async (progress) => {
107-
progress.report({message: `Ending current job`});
108+
window.withProgress({ location: ProgressLocation.Window }, async (progress) => {
109+
progress.report({ message: `Ending current job` });
108110

109111
await selected.job.close();
110112

111-
progress.report({message: `Starting new job`});
113+
progress.report({ message: `Starting new job` });
112114

113115
selected.job.options = newOptions;
114-
116+
115117
try {
116118
await selected.job.connect();
117119
} catch (e) {
@@ -125,6 +127,50 @@ export class JobManagerView implements TreeDataProvider<any> {
125127
}
126128
}),
127129

130+
vscode.commands.registerCommand(`vscode-db2i.jobManager.enableTracing`, async (node?: SQLJobItem) => {
131+
if (node) {
132+
const id = node.label as string;
133+
const selected = await JobManager.getJob(id);
134+
135+
ServerComponent.writeOutput(`Enabling tracing for ${selected.name} (${selected.job.id})`, true);
136+
137+
selected.job.setTraceConfig(ServerTraceDest.IN_MEM, ServerTraceLevel.DATASTREAM);
138+
}
139+
}),
140+
141+
vscode.commands.registerCommand(`vscode-db2i.jobManager.getTrace`, async (node?: SQLJobItem) => {
142+
if (node) {
143+
const id = node.label as string;
144+
const selected = await JobManager.getJob(id);
145+
146+
const possibleFile = selected.job.getTraceFilePath();
147+
148+
if (possibleFile) {
149+
// Trace was written to a file
150+
vscode.workspace.openTextDocument(Uri.from({
151+
scheme: `streamfile`,
152+
path: possibleFile
153+
})).then(doc => {
154+
vscode.window.showTextDocument(doc);
155+
});
156+
157+
} else {
158+
// This likely means IN_MEM was used
159+
const trace = await selected.job.getTraceData();
160+
if (trace.success) {
161+
vscode.workspace.openTextDocument({
162+
content: trace.tracedata.trim()
163+
}).then(doc => {
164+
vscode.window.showTextDocument(doc);
165+
})
166+
167+
} else {
168+
ServerComponent.writeOutput(`Unable to get trace data for ${selected.name} (${selected.job.id}):`, true);
169+
ServerComponent.writeOutput(trace.error);
170+
}
171+
}
172+
}
173+
}),
128174
vscode.commands.registerCommand(`vscode-db2i.jobManager.jobCommit`, async (node?: SQLJobItem) => {
129175
const id = node ? node.label as string : undefined;
130176
let selected = id ? JobManager.getJob(id) : JobManager.getSelection();
@@ -193,17 +239,17 @@ export class JobManagerView implements TreeDataProvider<any> {
193239
async getChildren(element: ConfigGroup): Promise<SQLJobItem[]> {
194240
if (element) {
195241
return ConfigManager.getConfigTreeItems();
196-
242+
197243
} else {
198-
let nodes =
244+
let nodes =
199245
JobManager
200246
.getRunningJobs()
201247
.map((info, index) => new SQLJobItem(info, index === JobManager.selectedJob));
202248

203249
if (ConfigManager.hasSavedItems()) {
204250
nodes.push(new ConfigGroup());
205251
}
206-
252+
207253
return nodes;
208254
}
209255
}

0 commit comments

Comments
 (0)