Skip to content

Commit 7e27f20

Browse files
committed
Specify custom directory for storing query server logs
1 parent f550cbe commit 7e27f20

File tree

5 files changed

+55
-13
lines changed

5 files changed

+55
-13
lines changed

extensions/ql-vscode/package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@
179179
"default": 20,
180180
"description": "Max number of simultaneous queries to run using the 'CodeQL: Run Queries' command."
181181
},
182+
"codeQL.runningQueries.customLogDirectory": {
183+
"type": [
184+
"string",
185+
null
186+
],
187+
"default": null,
188+
"description": "Path to a directory where the CodeQL extension should store query server logs. If empty, the extension stores logs in a temporary workspace folder and deletes the contents after each run."
189+
},
182190
"codeQL.resultsDisplay.pageSize": {
183191
"type": "integer",
184192
"default": 200,

extensions/ql-vscode/src/config.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,10 @@ export const NUMBER_OF_TEST_THREADS_SETTING = new Setting('numberOfThreads', RUN
8787
export const MAX_QUERIES = new Setting('maxQueries', RUNNING_QUERIES_SETTING);
8888
export const AUTOSAVE_SETTING = new Setting('autoSave', RUNNING_QUERIES_SETTING);
8989
export const PAGE_SIZE = new Setting('pageSize', RESULTS_DISPLAY_SETTING);
90+
const CUSTOM_LOG_DIRECTORY_SETTING = new Setting('customLogDirectory', RUNNING_QUERIES_SETTING);
9091

9192
/** When these settings change, the running query server should be restarted. */
92-
const QUERY_SERVER_RESTARTING_SETTINGS = [NUMBER_OF_THREADS_SETTING, SAVE_CACHE_SETTING, CACHE_SIZE_SETTING, MEMORY_SETTING, DEBUG_SETTING];
93+
const QUERY_SERVER_RESTARTING_SETTINGS = [NUMBER_OF_THREADS_SETTING, SAVE_CACHE_SETTING, CACHE_SIZE_SETTING, MEMORY_SETTING, DEBUG_SETTING, CUSTOM_LOG_DIRECTORY_SETTING];
9394

9495
export interface QueryServerConfig {
9596
codeQlPath: string;
@@ -99,6 +100,7 @@ export interface QueryServerConfig {
99100
cacheSize: number;
100101
queryMemoryMb?: number;
101102
timeoutSecs: number;
103+
customLogDirectory?: string;
102104
onDidChangeConfiguration?: Event<void>;
103105
}
104106

@@ -197,6 +199,10 @@ export class QueryServerConfigListener extends ConfigListener implements QuerySe
197199
return this._codeQlPath;
198200
}
199201

202+
public get customLogDirectory(): string | undefined {
203+
return CUSTOM_LOG_DIRECTORY_SETTING.getValue<string>() || undefined;
204+
}
205+
200206
public get numThreads(): number {
201207
return NUMBER_OF_THREADS_SETTING.getValue<number>();
202208
}

extensions/ql-vscode/src/extension.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ async function activateWithInstalledDistribution(
380380
cliServer,
381381
{
382382
logger: queryServerLogger,
383+
contextStoragePath: getContextStoragePath(ctx),
383384
},
384385
(task) =>
385386
Window.withProgress(
@@ -768,9 +769,8 @@ function getContextStoragePath(ctx: ExtensionContext) {
768769

769770
function initializeLogging(ctx: ExtensionContext): void {
770771
const storagePath = getContextStoragePath(ctx);
771-
logger.init(storagePath);
772-
queryServerLogger.init(storagePath);
773-
ideServerLogger.init(storagePath);
772+
logger.setLogStoragePath(storagePath, false);
773+
ideServerLogger.setLogStoragePath(storagePath, false);
774774
ctx.subscriptions.push(logger);
775775
ctx.subscriptions.push(queryServerLogger);
776776
ctx.subscriptions.push(ideServerLogger);

extensions/ql-vscode/src/logging.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,24 @@ export class OutputChannelLogger extends DisposableObject implements Logger {
4040
public readonly outputChannel: OutputChannel;
4141
private readonly additionalLocations = new Map<string, AdditionalLogLocation>();
4242
private additionalLogLocationPath: string | undefined;
43+
isCustomLogDirectory: boolean;
4344

4445
constructor(private title: string) {
4546
super();
4647
this.outputChannel = Window.createOutputChannel(title);
4748
this.push(this.outputChannel);
49+
this.isCustomLogDirectory = false;
4850
}
4951

50-
init(storagePath: string): void {
52+
setLogStoragePath(storagePath: string, isCustomLogDirectory: boolean): void {
5153
this.additionalLogLocationPath = path.join(storagePath, this.title);
5254

53-
// clear out any old state from previous runs
54-
fs.remove(this.additionalLogLocationPath);
55+
this.isCustomLogDirectory = isCustomLogDirectory;
56+
57+
if (!this.isCustomLogDirectory) {
58+
// clear out any old state from previous runs
59+
fs.remove(this.additionalLogLocationPath);
60+
}
5561
}
5662

5763
/**
@@ -80,7 +86,7 @@ export class OutputChannelLogger extends DisposableObject implements Logger {
8086
this.outputChannel.appendLine(separator);
8187
this.outputChannel.appendLine(msg);
8288
this.outputChannel.appendLine(separator);
83-
additional = new AdditionalLogLocation(logPath);
89+
additional = new AdditionalLogLocation(logPath, !this.isCustomLogDirectory);
8490
this.additionalLocations.set(logPath, additional);
8591
this.track(additional);
8692
}
@@ -112,7 +118,7 @@ export class OutputChannelLogger extends DisposableObject implements Logger {
112118
}
113119

114120
class AdditionalLogLocation extends Disposable {
115-
constructor(private location: string) {
121+
constructor(private location: string, private shouldDeleteLogs: boolean) {
116122
super(() => { /**/ });
117123
}
118124

@@ -128,7 +134,9 @@ class AdditionalLogLocation extends Disposable {
128134
}
129135

130136
async dispose(): Promise<void> {
131-
await fs.remove(this.location);
137+
if (this.shouldDeleteLogs) {
138+
await fs.remove(this.location);
139+
}
132140
}
133141
}
134142

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import { Disposable, CancellationToken, commands } from 'vscode';
55
import { createMessageConnection, MessageConnection, RequestType } from 'vscode-jsonrpc';
66
import * as cli from './cli';
77
import { QueryServerConfig } from './config';
8-
import { Logger, ProgressReporter } from './logging';
8+
import { Logger, ProgressReporter, queryServerLogger } from './logging';
99
import { completeQuery, EvaluationResult, progress, ProgressMessage, WithProgressId } from './pure/messages';
1010
import * as messages from './pure/messages';
1111
import { ProgressCallback, ProgressTask } from './commandRunner';
12+
import * as fs from 'fs-extra';
13+
import * as helpers from './helpers';
1214

1315
type ServerOpts = {
1416
logger: Logger;
17+
contextStoragePath: string;
1518
}
1619

1720
/** A running query server process and its associated message connection. */
@@ -86,8 +89,24 @@ export class QueryServerClient extends DisposableObject {
8689
this.evaluationResultCallbacks = {};
8790
}
8891

92+
initLogger() {
93+
let storagePath = this.opts.contextStoragePath;
94+
let isCustomLogDirectory = false;
95+
if (this.config.customLogDirectory) {
96+
if (fs.existsSync(this.config.customLogDirectory) && fs.statSync(this.config.customLogDirectory).isDirectory()) {
97+
storagePath = this.config.customLogDirectory;
98+
isCustomLogDirectory = true;
99+
} else if (this.config.customLogDirectory) {
100+
helpers.showAndLogErrorMessage(`${this.config.customLogDirectory} is not a valid directory. Logs will be stored in a temporary workspace directory instead.`);
101+
}
102+
}
103+
104+
queryServerLogger.setLogStoragePath(storagePath, isCustomLogDirectory);
105+
106+
}
107+
89108
get logger(): Logger {
90-
return this.opts.logger;
109+
return queryServerLogger;
91110
}
92111

93112
/** Stops the query server by disposing of the current server process. */
@@ -151,6 +170,7 @@ export class QueryServerClient extends DisposableObject {
151170
args.push('-J=-agentlib:jdwp=transport=dt_socket,address=localhost:9010,server=y,suspend=n,quiet=y');
152171
}
153172

173+
this.initLogger();
154174
const child = cli.spawnServer(
155175
this.config.codeQlPath,
156176
'CodeQL query server',
@@ -185,7 +205,7 @@ export class QueryServerClient extends DisposableObject {
185205
callback(res);
186206
}
187207
});
188-
this.serverProcess = new ServerProcess(child, connection, this.opts.logger);
208+
this.serverProcess = new ServerProcess(child, connection, this.logger);
189209
// Ensure the server process is disposed together with this client.
190210
this.track(this.serverProcess);
191211
connection.listen();

0 commit comments

Comments
 (0)