Skip to content

Commit cc1bf74

Browse files
authored
Print end-of-query summary logs to Query Server Console (#1264)
* Log new end summary file to query server console * Change supported CLI version to 2.9.0
1 parent 2f79087 commit cc1bf74

7 files changed

Lines changed: 64 additions & 22 deletions

File tree

extensions/ql-vscode/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- Avoid synchronizing the `codeQL.cli.executablePath` setting. [#1252](https://github.com/github/vscode-codeql/pull/1252)
77
- Open the directory in the finder/explorer (instead of just highlighting it) when running the "Open query directory" command from the query history view. [#1235](https://github.com/github/vscode-codeql/pull/1235)
88
- Ensure query label in the query history view changes are persisted across restarts. [#1235](https://github.com/github/vscode-codeql/pull/1235)
9+
- Prints end-of-query evaluator log summaries to the Query Server Console. [#1264](https://github.com/github/vscode-codeql/pull/1264)
910

1011
## 1.6.1 - 17 March 2022
1112

extensions/ql-vscode/src/cli.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,15 +667,18 @@ export class CodeQLCliServer implements Disposable {
667667

668668
/**
669669
* Generate a summary of an evaluation log.
670+
* @param endSummaryPath The path to write only the end of query part of the human-readable summary to.
670671
* @param inputPath The path of an evaluation event log.
671672
* @param outputPath The path to write a human-readable summary of it to.
672673
*/
673674
async generateLogSummary(
674675
inputPath: string,
675676
outputPath: string,
677+
endSummaryPath: string,
676678
): Promise<string> {
677679
const subcommandArgs = [
678680
'--format=text',
681+
`--end-summary=${endSummaryPath}`,
679682
inputPath,
680683
outputPath
681684
];
@@ -1279,8 +1282,14 @@ export class CliVersionConstraint {
12791282

12801283
/**
12811284
* CLI version that supports rotating structured logs to produce one per query.
1285+
*
1286+
* Note that 2.8.4 supports generating the evaluation logs and summaries,
1287+
* but 2.9.0 includes a new option to produce the end-of-query summary logs to
1288+
* the query server console. For simplicity we gate all features behind 2.9.0,
1289+
* but if a user is tied to the 2.8 release, we can enable evaluator logs
1290+
* and summaries for them.
12821291
*/
1283-
public static CLI_VERSION_WITH_PER_QUERY_EVAL_LOG = new SemVer('2.8.4');
1292+
public static CLI_VERSION_WITH_PER_QUERY_EVAL_LOG = new SemVer('2.9.0');
12841293

12851294
constructor(private readonly cli: CodeQLCliServer) {
12861295
/**/

extensions/ql-vscode/src/pure/messages.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ export interface StartLogResult {
722722
}
723723

724724
/**
725-
* The result of terminating a structured.
725+
* The result of terminating a structured log.
726726
*/
727727
export interface EndLogResult {
728728
/**

extensions/ql-vscode/src/query-history.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,11 @@ export class QueryHistoryManager extends DisposableObject {
781781
void showAndLogWarningMessage('No evaluator log is available for this run. Perhaps it failed before evaluation, or you are running with a version of CodeQL before ' + CliVersionConstraint.CLI_VERSION_WITH_PER_QUERY_EVAL_LOG + '?');
782782
}
783783

784+
private warnNoEvalLogSummary() {
785+
void showAndLogWarningMessage(`No evaluator log summary is available for this run. Perhaps it failed before evaluation, or you are running with a version of CodeQL before ${CliVersionConstraint.CLI_VERSION_WITH_PER_QUERY_EVAL_LOG}?`);
786+
}
787+
788+
784789
async handleShowEvalLog(
785790
singleItem: QueryHistoryInfo,
786791
multiSelect: QueryHistoryInfo[]
@@ -810,13 +815,10 @@ export class QueryHistoryManager extends DisposableObject {
810815
return;
811816
}
812817

813-
if (finalSingleItem.evalLogLocation) {
814-
if (!fs.existsSync(finalSingleItem.evalLogSummaryLocation)) {
815-
await this.qs.cliServer.generateLogSummary(finalSingleItem.evalLogLocation, finalSingleItem.evalLogSummaryLocation);
816-
}
817-
await this.tryOpenExternalFile(finalSingleItem.evalLogSummaryLocation);
818+
if (finalSingleItem.evalLogSummaryLocation) {
819+
await this.tryOpenExternalFile(finalSingleItem.evalLogSummaryLocation);
818820
} else {
819-
this.warnNoEvalLog();
821+
this.warnNoEvalLogSummary();
820822
}
821823
}
822824

extensions/ql-vscode/src/query-results.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ export class LocalQueryInfo {
217217
public failureReason: string | undefined;
218218
public completedQuery: CompletedQueryInfo | undefined;
219219
public evalLogLocation: string | undefined;
220+
public evalLogSummaryLocation: string | undefined;
220221
private config: QueryHistoryConfig | undefined;
221222

222223
/**
@@ -312,14 +313,6 @@ export class LocalQueryInfo {
312313
}
313314
}
314315

315-
/**
316-
* Return the location of a query's evaluator log summary. This file may not exist yet,
317-
* in which case it can be created by invoking `codeql generate log-summary`.
318-
*/
319-
get evalLogSummaryLocation(): string {
320-
return this.evalLogLocation + '.summary';
321-
}
322-
323316
get completed(): boolean {
324317
return !!this.completedQuery;
325318
}

extensions/ql-vscode/src/queryserver-client.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ export function findQueryLogFile(resultPath: string): string {
259259
return path.join(resultPath, 'query.log');
260260
}
261261

262-
export function findQueryStructLogFile(resultPath: string): string {
262+
export function findQueryEvalLogFile(resultPath: string): string {
263263
return path.join(resultPath, 'evaluator-log.jsonl');
264264
}
265+
266+
export function findQueryEvalLogSummaryFile(resultPath: string): string {
267+
return path.join(resultPath, 'evaluator-log.summary');
268+
}
269+
270+
export function findQueryEvalLogEndSummaryFile(resultPath: string): string {
271+
return path.join(resultPath, 'evaluator-log-end.summary');
272+
}

extensions/ql-vscode/src/run-queries.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,16 @@ export class QueryEvaluationInfo {
9595
return qsClient.findQueryLogFile(this.querySaveDir);
9696
}
9797

98-
get structLogPath() {
99-
return qsClient.findQueryStructLogFile(this.querySaveDir);
98+
get evalLogPath() {
99+
return qsClient.findQueryEvalLogFile(this.querySaveDir);
100+
}
101+
102+
get evalLogSummaryPath() {
103+
return qsClient.findQueryEvalLogSummaryFile(this.querySaveDir);
104+
}
105+
106+
get evalLogEndSummaryPath() {
107+
return qsClient.findQueryEvalLogEndSummaryFile(this.querySaveDir);
100108
}
101109

102110
get resultsPaths() {
@@ -164,8 +172,9 @@ export class QueryEvaluationInfo {
164172
if (queryInfo && await qs.cliServer.cliConstraints.supportsPerQueryEvalLog()) {
165173
await qs.sendRequest(messages.startLog, {
166174
db: dataset,
167-
logPath: this.structLogPath,
175+
logPath: this.evalLogPath,
168176
});
177+
169178
}
170179
const params: messages.EvaluateQueriesParams = {
171180
db: dataset,
@@ -186,9 +195,22 @@ export class QueryEvaluationInfo {
186195
if (queryInfo && await qs.cliServer.cliConstraints.supportsPerQueryEvalLog()) {
187196
await qs.sendRequest(messages.endLog, {
188197
db: dataset,
189-
logPath: this.structLogPath,
198+
logPath: this.evalLogPath,
190199
});
191-
queryInfo.evalLogLocation = this.structLogPath;
200+
if (await this.hasEvalLog()) {
201+
queryInfo.evalLogLocation = this.evalLogPath;
202+
await qs.cliServer.generateLogSummary(this.evalLogPath, this.evalLogSummaryPath, this.evalLogEndSummaryPath);
203+
queryInfo.evalLogSummaryLocation = this.evalLogSummaryPath;
204+
fs.readFile(this.evalLogEndSummaryPath, (err, buffer) => {
205+
if (err) {
206+
throw new Error(`Could not read structured evaluator log end of summary file at ${this.evalLogEndSummaryPath}.`);
207+
}
208+
void qs.logger.log(' --- Evaluator Log Summary --- ');
209+
void qs.logger.log(buffer.toString());
210+
});
211+
} else {
212+
void showAndLogWarningMessage(`Failed to write structured evaluator log to ${this.evalLogPath}.`);
213+
}
192214
}
193215
}
194216
return result || {
@@ -303,6 +325,13 @@ export class QueryEvaluationInfo {
303325
return this.dilPath;
304326
}
305327

328+
/**
329+
* Holds if this query already has a completed structured evaluator log
330+
*/
331+
async hasEvalLog(): Promise<boolean> {
332+
return fs.pathExists(this.evalLogPath);
333+
}
334+
306335
/**
307336
* Creates the CSV file containing the results of this query. This will only be called if the query
308337
* does not have interpreted results and the CSV file does not already exist.

0 commit comments

Comments
 (0)