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
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
- Avoid synchronizing the `codeQL.cli.executablePath` setting. [#1252](https://github.com/github/vscode-codeql/pull/1252)
|
- Avoid synchronizing the `codeQL.cli.executablePath` setting. [#1252](https://github.com/github/vscode-codeql/pull/1252)
|
||||||
- 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)
|
- 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)
|
||||||
- Ensure query label in the query history view changes are persisted across restarts. [#1235](https://github.com/github/vscode-codeql/pull/1235)
|
- Ensure query label in the query history view changes are persisted across restarts. [#1235](https://github.com/github/vscode-codeql/pull/1235)
|
||||||
|
- Prints end-of-query evaluator log summaries to the Query Server Console. [#1264](https://github.com/github/vscode-codeql/pull/1264)
|
||||||
|
|
||||||
## 1.6.1 - 17 March 2022
|
## 1.6.1 - 17 March 2022
|
||||||
|
|
||||||
|
|||||||
@@ -667,15 +667,18 @@ export class CodeQLCliServer implements Disposable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a summary of an evaluation log.
|
* Generate a summary of an evaluation log.
|
||||||
|
* @param endSummaryPath The path to write only the end of query part of the human-readable summary to.
|
||||||
* @param inputPath The path of an evaluation event log.
|
* @param inputPath The path of an evaluation event log.
|
||||||
* @param outputPath The path to write a human-readable summary of it to.
|
* @param outputPath The path to write a human-readable summary of it to.
|
||||||
*/
|
*/
|
||||||
async generateLogSummary(
|
async generateLogSummary(
|
||||||
inputPath: string,
|
inputPath: string,
|
||||||
outputPath: string,
|
outputPath: string,
|
||||||
|
endSummaryPath: string,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const subcommandArgs = [
|
const subcommandArgs = [
|
||||||
'--format=text',
|
'--format=text',
|
||||||
|
`--end-summary=${endSummaryPath}`,
|
||||||
inputPath,
|
inputPath,
|
||||||
outputPath
|
outputPath
|
||||||
];
|
];
|
||||||
@@ -1279,8 +1282,14 @@ export class CliVersionConstraint {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* CLI version that supports rotating structured logs to produce one per query.
|
* CLI version that supports rotating structured logs to produce one per query.
|
||||||
|
*
|
||||||
|
* Note that 2.8.4 supports generating the evaluation logs and summaries,
|
||||||
|
* but 2.9.0 includes a new option to produce the end-of-query summary logs to
|
||||||
|
* the query server console. For simplicity we gate all features behind 2.9.0,
|
||||||
|
* but if a user is tied to the 2.8 release, we can enable evaluator logs
|
||||||
|
* and summaries for them.
|
||||||
*/
|
*/
|
||||||
public static CLI_VERSION_WITH_PER_QUERY_EVAL_LOG = new SemVer('2.8.4');
|
public static CLI_VERSION_WITH_PER_QUERY_EVAL_LOG = new SemVer('2.9.0');
|
||||||
|
|
||||||
constructor(private readonly cli: CodeQLCliServer) {
|
constructor(private readonly cli: CodeQLCliServer) {
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@@ -722,7 +722,7 @@ export interface StartLogResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The result of terminating a structured.
|
* The result of terminating a structured log.
|
||||||
*/
|
*/
|
||||||
export interface EndLogResult {
|
export interface EndLogResult {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -781,6 +781,11 @@ export class QueryHistoryManager extends DisposableObject {
|
|||||||
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 + '?');
|
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 + '?');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private warnNoEvalLogSummary() {
|
||||||
|
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}?`);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async handleShowEvalLog(
|
async handleShowEvalLog(
|
||||||
singleItem: QueryHistoryInfo,
|
singleItem: QueryHistoryInfo,
|
||||||
multiSelect: QueryHistoryInfo[]
|
multiSelect: QueryHistoryInfo[]
|
||||||
@@ -810,13 +815,10 @@ export class QueryHistoryManager extends DisposableObject {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalSingleItem.evalLogLocation) {
|
if (finalSingleItem.evalLogSummaryLocation) {
|
||||||
if (!fs.existsSync(finalSingleItem.evalLogSummaryLocation)) {
|
await this.tryOpenExternalFile(finalSingleItem.evalLogSummaryLocation);
|
||||||
await this.qs.cliServer.generateLogSummary(finalSingleItem.evalLogLocation, finalSingleItem.evalLogSummaryLocation);
|
|
||||||
}
|
|
||||||
await this.tryOpenExternalFile(finalSingleItem.evalLogSummaryLocation);
|
|
||||||
} else {
|
} else {
|
||||||
this.warnNoEvalLog();
|
this.warnNoEvalLogSummary();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ export class LocalQueryInfo {
|
|||||||
public failureReason: string | undefined;
|
public failureReason: string | undefined;
|
||||||
public completedQuery: CompletedQueryInfo | undefined;
|
public completedQuery: CompletedQueryInfo | undefined;
|
||||||
public evalLogLocation: string | undefined;
|
public evalLogLocation: string | undefined;
|
||||||
|
public evalLogSummaryLocation: string | undefined;
|
||||||
private config: QueryHistoryConfig | undefined;
|
private config: QueryHistoryConfig | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -312,14 +313,6 @@ export class LocalQueryInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the location of a query's evaluator log summary. This file may not exist yet,
|
|
||||||
* in which case it can be created by invoking `codeql generate log-summary`.
|
|
||||||
*/
|
|
||||||
get evalLogSummaryLocation(): string {
|
|
||||||
return this.evalLogLocation + '.summary';
|
|
||||||
}
|
|
||||||
|
|
||||||
get completed(): boolean {
|
get completed(): boolean {
|
||||||
return !!this.completedQuery;
|
return !!this.completedQuery;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,6 +259,14 @@ export function findQueryLogFile(resultPath: string): string {
|
|||||||
return path.join(resultPath, 'query.log');
|
return path.join(resultPath, 'query.log');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findQueryStructLogFile(resultPath: string): string {
|
export function findQueryEvalLogFile(resultPath: string): string {
|
||||||
return path.join(resultPath, 'evaluator-log.jsonl');
|
return path.join(resultPath, 'evaluator-log.jsonl');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function findQueryEvalLogSummaryFile(resultPath: string): string {
|
||||||
|
return path.join(resultPath, 'evaluator-log.summary');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findQueryEvalLogEndSummaryFile(resultPath: string): string {
|
||||||
|
return path.join(resultPath, 'evaluator-log-end.summary');
|
||||||
|
}
|
||||||
@@ -95,8 +95,16 @@ export class QueryEvaluationInfo {
|
|||||||
return qsClient.findQueryLogFile(this.querySaveDir);
|
return qsClient.findQueryLogFile(this.querySaveDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
get structLogPath() {
|
get evalLogPath() {
|
||||||
return qsClient.findQueryStructLogFile(this.querySaveDir);
|
return qsClient.findQueryEvalLogFile(this.querySaveDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
get evalLogSummaryPath() {
|
||||||
|
return qsClient.findQueryEvalLogSummaryFile(this.querySaveDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
get evalLogEndSummaryPath() {
|
||||||
|
return qsClient.findQueryEvalLogEndSummaryFile(this.querySaveDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
get resultsPaths() {
|
get resultsPaths() {
|
||||||
@@ -164,8 +172,9 @@ export class QueryEvaluationInfo {
|
|||||||
if (queryInfo && await qs.cliServer.cliConstraints.supportsPerQueryEvalLog()) {
|
if (queryInfo && await qs.cliServer.cliConstraints.supportsPerQueryEvalLog()) {
|
||||||
await qs.sendRequest(messages.startLog, {
|
await qs.sendRequest(messages.startLog, {
|
||||||
db: dataset,
|
db: dataset,
|
||||||
logPath: this.structLogPath,
|
logPath: this.evalLogPath,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
const params: messages.EvaluateQueriesParams = {
|
const params: messages.EvaluateQueriesParams = {
|
||||||
db: dataset,
|
db: dataset,
|
||||||
@@ -186,9 +195,22 @@ export class QueryEvaluationInfo {
|
|||||||
if (queryInfo && await qs.cliServer.cliConstraints.supportsPerQueryEvalLog()) {
|
if (queryInfo && await qs.cliServer.cliConstraints.supportsPerQueryEvalLog()) {
|
||||||
await qs.sendRequest(messages.endLog, {
|
await qs.sendRequest(messages.endLog, {
|
||||||
db: dataset,
|
db: dataset,
|
||||||
logPath: this.structLogPath,
|
logPath: this.evalLogPath,
|
||||||
});
|
});
|
||||||
queryInfo.evalLogLocation = this.structLogPath;
|
if (await this.hasEvalLog()) {
|
||||||
|
queryInfo.evalLogLocation = this.evalLogPath;
|
||||||
|
await qs.cliServer.generateLogSummary(this.evalLogPath, this.evalLogSummaryPath, this.evalLogEndSummaryPath);
|
||||||
|
queryInfo.evalLogSummaryLocation = this.evalLogSummaryPath;
|
||||||
|
fs.readFile(this.evalLogEndSummaryPath, (err, buffer) => {
|
||||||
|
if (err) {
|
||||||
|
throw new Error(`Could not read structured evaluator log end of summary file at ${this.evalLogEndSummaryPath}.`);
|
||||||
|
}
|
||||||
|
void qs.logger.log(' --- Evaluator Log Summary --- ');
|
||||||
|
void qs.logger.log(buffer.toString());
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
void showAndLogWarningMessage(`Failed to write structured evaluator log to ${this.evalLogPath}.`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result || {
|
return result || {
|
||||||
@@ -303,6 +325,13 @@ export class QueryEvaluationInfo {
|
|||||||
return this.dilPath;
|
return this.dilPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this query already has a completed structured evaluator log
|
||||||
|
*/
|
||||||
|
async hasEvalLog(): Promise<boolean> {
|
||||||
|
return fs.pathExists(this.evalLogPath);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the CSV file containing the results of this query. This will only be called if the query
|
* Creates the CSV file containing the results of this query. This will only be called if the query
|
||||||
* does not have interpreted results and the CSV file does not already exist.
|
* does not have interpreted results and the CSV file does not already exist.
|
||||||
|
|||||||
Reference in New Issue
Block a user