Add the CLI version to telemetry events
This adds the CLI version to telemetry command-usage events. Note that the CLI server is created after the telemetry listener is created. The first few telemetry events may have a "not-set" value for the CLI version.
This commit is contained in:
@@ -75,7 +75,7 @@ export function registerCommandWithErrorHandling(
|
|||||||
return undefined;
|
return undefined;
|
||||||
} finally {
|
} finally {
|
||||||
const executionTime = Date.now() - startTime;
|
const executionTime = Date.now() - startTime;
|
||||||
telemetryListener?.sendCommandUsage(commandId, executionTime, error);
|
void telemetryListener?.sendCommandUsage(commandId, executionTime, error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ export async function activate(
|
|||||||
|
|
||||||
const distributionConfigListener = new DistributionConfigListener();
|
const distributionConfigListener = new DistributionConfigListener();
|
||||||
await initializeLogging(ctx);
|
await initializeLogging(ctx);
|
||||||
await initializeTelemetry(extension, ctx);
|
const telemetryListener = await initializeTelemetry(extension, ctx);
|
||||||
addUnhandledRejectionListener();
|
addUnhandledRejectionListener();
|
||||||
install();
|
install();
|
||||||
|
|
||||||
@@ -395,6 +395,7 @@ export async function activate(
|
|||||||
variantAnalysisViewSerializer.onExtensionLoaded(
|
variantAnalysisViewSerializer.onExtensionLoaded(
|
||||||
codeQlExtension.variantAnalysisManager,
|
codeQlExtension.variantAnalysisManager,
|
||||||
);
|
);
|
||||||
|
telemetryListener.cli = codeQlExtension.cliServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
return codeQlExtension;
|
return codeQlExtension;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { extLogger } from "./common";
|
|||||||
import { UserCancellationException } from "./progress";
|
import { UserCancellationException } from "./progress";
|
||||||
import { showBinaryChoiceWithUrlDialog } from "./helpers";
|
import { showBinaryChoiceWithUrlDialog } from "./helpers";
|
||||||
import { RedactableError } from "./pure/errors";
|
import { RedactableError } from "./pure/errors";
|
||||||
|
import { CodeQLCliServer } from "./cli";
|
||||||
|
|
||||||
// Key is injected at build time through the APP_INSIGHTS_KEY environment variable.
|
// Key is injected at build time through the APP_INSIGHTS_KEY environment variable.
|
||||||
const key = "REPLACE-APP-INSIGHTS-KEY";
|
const key = "REPLACE-APP-INSIGHTS-KEY";
|
||||||
@@ -56,6 +57,8 @@ export class TelemetryListener extends ConfigListener {
|
|||||||
|
|
||||||
private reporter?: TelemetryReporter;
|
private reporter?: TelemetryReporter;
|
||||||
|
|
||||||
|
private _cli?: CodeQLCliServer;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly id: string,
|
private readonly id: string,
|
||||||
private readonly version: string,
|
private readonly version: string,
|
||||||
@@ -147,7 +150,7 @@ export class TelemetryListener extends ConfigListener {
|
|||||||
void this.reporter?.dispose();
|
void this.reporter?.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommandUsage(name: string, executionTime: number, error?: Error) {
|
async sendCommandUsage(name: string, executionTime: number, error?: Error) {
|
||||||
if (!this.reporter) {
|
if (!this.reporter) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -157,12 +160,18 @@ export class TelemetryListener extends ConfigListener {
|
|||||||
? CommandCompletion.Cancelled
|
? CommandCompletion.Cancelled
|
||||||
: CommandCompletion.Failed;
|
: CommandCompletion.Failed;
|
||||||
|
|
||||||
|
const cliVersion = this._cli
|
||||||
|
? (await this._cli.getVersion()).toString()
|
||||||
|
: // telemetry events that are sent before the cli is initialized will not have a version number
|
||||||
|
"not-set";
|
||||||
|
|
||||||
this.reporter.sendTelemetryEvent(
|
this.reporter.sendTelemetryEvent(
|
||||||
"command-usage",
|
"command-usage",
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
status,
|
status,
|
||||||
isCanary: isCanary().toString(),
|
isCanary: isCanary().toString(),
|
||||||
|
cliVersion,
|
||||||
},
|
},
|
||||||
{ executionTime },
|
{ executionTime },
|
||||||
);
|
);
|
||||||
@@ -241,6 +250,10 @@ export class TelemetryListener extends ConfigListener {
|
|||||||
return this.reporter;
|
return this.reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set cli(cli: CodeQLCliServer) {
|
||||||
|
this._cli = cli;
|
||||||
|
}
|
||||||
|
|
||||||
private disposeReporter() {
|
private disposeReporter() {
|
||||||
if (this.reporter) {
|
if (this.reporter) {
|
||||||
void this.reporter.dispose();
|
void this.reporter.dispose();
|
||||||
@@ -265,7 +278,7 @@ export let telemetryListener: TelemetryListener | undefined;
|
|||||||
export async function initializeTelemetry(
|
export async function initializeTelemetry(
|
||||||
extension: Extension<any>,
|
extension: Extension<any>,
|
||||||
ctx: ExtensionContext,
|
ctx: ExtensionContext,
|
||||||
): Promise<void> {
|
): Promise<TelemetryListener> {
|
||||||
if (telemetryListener !== undefined) {
|
if (telemetryListener !== undefined) {
|
||||||
throw new Error("Telemetry is already initialized");
|
throw new Error("Telemetry is already initialized");
|
||||||
}
|
}
|
||||||
@@ -279,4 +292,5 @@ export async function initializeTelemetry(
|
|||||||
// this is a particular problem during integration tests, which will hang if a modal popup is displayed.
|
// this is a particular problem during integration tests, which will hang if a modal popup is displayed.
|
||||||
void telemetryListener.initialize();
|
void telemetryListener.initialize();
|
||||||
ctx.subscriptions.push(telemetryListener);
|
ctx.subscriptions.push(telemetryListener);
|
||||||
|
return telemetryListener;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ describe("telemetry reporting", () => {
|
|||||||
it("should send an event", async () => {
|
it("should send an event", async () => {
|
||||||
await telemetryListener.initialize();
|
await telemetryListener.initialize();
|
||||||
|
|
||||||
telemetryListener.sendCommandUsage("command-id", 1234, undefined);
|
await telemetryListener.sendCommandUsage("command-id", 1234, undefined);
|
||||||
|
|
||||||
expect(sendTelemetryEventSpy).toHaveBeenCalledWith(
|
expect(sendTelemetryEventSpy).toHaveBeenCalledWith(
|
||||||
"command-usage",
|
"command-usage",
|
||||||
@@ -193,6 +193,7 @@ describe("telemetry reporting", () => {
|
|||||||
name: "command-id",
|
name: "command-id",
|
||||||
status: "Success",
|
status: "Success",
|
||||||
isCanary,
|
isCanary,
|
||||||
|
cliVersion: "not-set",
|
||||||
},
|
},
|
||||||
{ executionTime: 1234 },
|
{ executionTime: 1234 },
|
||||||
);
|
);
|
||||||
@@ -203,7 +204,7 @@ describe("telemetry reporting", () => {
|
|||||||
it("should send a command usage event with an error", async () => {
|
it("should send a command usage event with an error", async () => {
|
||||||
await telemetryListener.initialize();
|
await telemetryListener.initialize();
|
||||||
|
|
||||||
telemetryListener.sendCommandUsage(
|
await telemetryListener.sendCommandUsage(
|
||||||
"command-id",
|
"command-id",
|
||||||
1234,
|
1234,
|
||||||
new UserCancellationException(),
|
new UserCancellationException(),
|
||||||
@@ -215,6 +216,33 @@ describe("telemetry reporting", () => {
|
|||||||
name: "command-id",
|
name: "command-id",
|
||||||
status: "Cancelled",
|
status: "Cancelled",
|
||||||
isCanary,
|
isCanary,
|
||||||
|
cliVersion: "not-set",
|
||||||
|
},
|
||||||
|
{ executionTime: 1234 },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(sendTelemetryExceptionSpy).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should send a command usage event with a cli version", async () => {
|
||||||
|
await telemetryListener.initialize();
|
||||||
|
telemetryListener.cli = {
|
||||||
|
getVersion: () => Promise.resolve("1.2.3"),
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
await telemetryListener.sendCommandUsage(
|
||||||
|
"command-id",
|
||||||
|
1234,
|
||||||
|
new UserCancellationException(),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(sendTelemetryEventSpy).toHaveBeenCalledWith(
|
||||||
|
"command-usage",
|
||||||
|
{
|
||||||
|
name: "command-id",
|
||||||
|
status: "Cancelled",
|
||||||
|
isCanary,
|
||||||
|
cliVersion: "1.2.3",
|
||||||
},
|
},
|
||||||
{ executionTime: 1234 },
|
{ executionTime: 1234 },
|
||||||
);
|
);
|
||||||
@@ -226,8 +254,8 @@ describe("telemetry reporting", () => {
|
|||||||
await telemetryListener.initialize();
|
await telemetryListener.initialize();
|
||||||
await enableTelemetry("codeQL.telemetry", false);
|
await enableTelemetry("codeQL.telemetry", false);
|
||||||
|
|
||||||
telemetryListener.sendCommandUsage("command-id", 1234, undefined);
|
await telemetryListener.sendCommandUsage("command-id", 1234, undefined);
|
||||||
telemetryListener.sendCommandUsage("command-id", 1234, new Error());
|
await telemetryListener.sendCommandUsage("command-id", 1234, new Error());
|
||||||
|
|
||||||
expect(sendTelemetryEventSpy).not.toBeCalled();
|
expect(sendTelemetryEventSpy).not.toBeCalled();
|
||||||
expect(sendTelemetryExceptionSpy).not.toBeCalled();
|
expect(sendTelemetryExceptionSpy).not.toBeCalled();
|
||||||
@@ -238,7 +266,7 @@ describe("telemetry reporting", () => {
|
|||||||
await enableTelemetry("codeQL.telemetry", false);
|
await enableTelemetry("codeQL.telemetry", false);
|
||||||
await enableTelemetry("codeQL.telemetry", true);
|
await enableTelemetry("codeQL.telemetry", true);
|
||||||
|
|
||||||
telemetryListener.sendCommandUsage("command-id", 1234, undefined);
|
await telemetryListener.sendCommandUsage("command-id", 1234, undefined);
|
||||||
|
|
||||||
expect(sendTelemetryEventSpy).toHaveBeenCalledWith(
|
expect(sendTelemetryEventSpy).toHaveBeenCalledWith(
|
||||||
"command-usage",
|
"command-usage",
|
||||||
@@ -246,6 +274,7 @@ describe("telemetry reporting", () => {
|
|||||||
name: "command-id",
|
name: "command-id",
|
||||||
status: "Success",
|
status: "Success",
|
||||||
isCanary,
|
isCanary,
|
||||||
|
cliVersion: "not-set",
|
||||||
},
|
},
|
||||||
{ executionTime: 1234 },
|
{ executionTime: 1234 },
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user