Skip to content

Commit d80127f

Browse files
authored
[VS Code] Add more metrics (#9299)
* Add some metrics in VS Code * revert * m * bug * more metrics * m
1 parent b2a998d commit d80127f

File tree

6 files changed

+60
-42
lines changed

6 files changed

+60
-42
lines changed

firebase-vscode/src/analytics.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,20 @@ export enum DATA_CONNECT_EVENT_NAME {
2121
PROJECT_SELECTED = "project_selected",
2222
RUN_LOCAL = "run_local",
2323
RUN_PROD = "run_prod",
24+
RUN_PROD_MUTATION_WARNING = "run_prod_mutation_warning",
25+
RUN_PROD_MUTATION_WARNING_REJECTED = "run_prod_mutation_warning_rejected",
26+
RUN_PROD_MUTATION_WARNING_ACKED = "run_prod_mutation_warning_acked",
27+
RUN_PROD_MUTATION_WARNING_ACKED_ALWAYS = "run_prod_mutation_warning_acked_always",
28+
MISSING_VARIABLES = "missing_variables",
2429
GENERATE_OPERATION = "generate_operation",
30+
GIF_TOS_MODAL = "gif_tos_modal",
31+
GIF_TOS_MODAL_ACKED = "gif_tos_modal_acked",
32+
GIF_TOS_MODAL_CLICKED = "gif_tos_modal_clicked",
33+
GIF_TOS_MODAL_REJECTED = "gif_tos_modal_rejected",
2534
ADD_DATA = "add_data",
2635
READ_DATA = "read_data",
2736
MOVE_TO_CONNECTOR = "move_to_connector",
2837
START_EMULATOR_FROM_EXECUTION = "start_emulator_from_execution",
29-
REFUSE_START_EMULATOR_FROM_EXECUTION = "refuse_start_emulator_from_execution",
3038
INIT = "init",
3139
INIT_SDK = "init_sdk",
3240
INIT_SDK_CLI = "init_sdk_cli",
@@ -36,11 +44,6 @@ export enum DATA_CONNECT_EVENT_NAME {
3644
SESSION_CHAR_COUNT = "session_char_count",
3745
EMULATOR_EXPORT = "emulator_export",
3846
SETUP_FIREBASE_BINARY = "setup_firebase_binary",
39-
GEMINI_ERROR = "gemini_error",
40-
GEMINI_OPERATION_CALL = "gemini_operation_call",
41-
GEMINI_SCHEMA_CALL = "gemini_schema_call",
42-
GEMINI_SUCCESS = "gemini_success",
43-
TRY_GEMINI_CLICKED = "try_gemini_clicked",
4447
TRY_FIREBASE_AGENT_CLICKED = "try_firebase_agent_in_gemini_clicked",
4548
MCP_DOCS_CLICKED = "mcp_docs_clicked",
4649
GIF_TOS_CLICKED = "gif_tos_clicked",

firebase-vscode/src/data-connect/ai-tools/firebase-mcp.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import {
2-
gemini,
3-
gemini as geminiToolModule,
4-
} from "../../../../src/init/features/aitools/gemini";
1+
import { gemini as geminiToolModule } from "../../../../src/init/features/aitools/gemini";
52
import * as vscode from "vscode";
63
import { firebaseConfig } from "../config";
74
import { ExtensionBrokerImpl } from "../../extension-broker";
85
import { AnalyticsLogger, DATA_CONNECT_EVENT_NAME } from "../../analytics";
6+
import { configstore } from "../../../../src/configstore";
97

108
const GEMINI_EXTENSION_ID = "google.geminicodeassist";
119

@@ -49,6 +47,7 @@ async function ensureGeminiExtension(): Promise<boolean> {
4947

5048
// Writes MCP config, then opens up Gemini with a new chat
5149
async function openGeminiChat() {
50+
configstore.set("gemini", true);
5251
writeToGeminiConfig();
5352
await vscode.commands.executeCommand("cloudcode.gemini.chatView.focus");
5453
await vscode.commands.executeCommand("geminicodeassist.agent.chat.new");

firebase-vscode/src/data-connect/execution/execution.ts

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ export function registerExecution(
130130
{ document, documentPath, position }: OperationLocation,
131131
instance: InstanceType,
132132
) {
133+
analyticsLogger.logger.logUsage(
134+
instance === InstanceType.LOCAL
135+
? DATA_CONNECT_EVENT_NAME.RUN_LOCAL
136+
: DATA_CONNECT_EVENT_NAME.RUN_PROD,
137+
);
138+
analyticsLogger.logger.logUsage(
139+
instance === InstanceType.LOCAL
140+
? DATA_CONNECT_EVENT_NAME.RUN_LOCAL + `_${ast.operation}`
141+
: DATA_CONNECT_EVENT_NAME.RUN_PROD + `_${ast.operation}`,
142+
);
143+
await vscode.window.activeTextEditor?.document.save();
144+
133145
// hold last execution in memory, and send operation name to webview
134146
lastExecutionInputSignal.value = {
135147
ast,
@@ -170,6 +182,7 @@ export function registerExecution(
170182
!configs.get(alwaysExecuteMutationsInProduction) &&
171183
ast.operation === OperationTypeNode.MUTATION
172184
) {
185+
analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.RUN_PROD_MUTATION_WARNING);
173186
const always = "Yes (always)";
174187
const yes = "Yes";
175188
const result = await vscode.window.showWarningMessage(
@@ -179,17 +192,28 @@ export function registerExecution(
179192
always,
180193
);
181194

182-
if (result !== always && result !== yes) {
183-
return;
184-
}
185-
186-
// If the user selects "always", we update User settings.
187-
if (result === always) {
188-
configs.update(
189-
alwaysExecuteMutationsInProduction,
190-
true,
191-
ConfigurationTarget.Global,
192-
);
195+
switch (result) {
196+
case yes:
197+
analyticsLogger.logger.logUsage(
198+
DATA_CONNECT_EVENT_NAME.RUN_PROD_MUTATION_WARNING_ACKED
199+
);
200+
break;
201+
case always:
202+
// If the user selects "always", we update User settings.
203+
configs.update(
204+
alwaysExecuteMutationsInProduction,
205+
true,
206+
ConfigurationTarget.Global,
207+
);
208+
analyticsLogger.logger.logUsage(
209+
DATA_CONNECT_EVENT_NAME.RUN_PROD_MUTATION_WARNING_ACKED_ALWAYS
210+
);
211+
break;
212+
default:
213+
analyticsLogger.logger.logUsage(
214+
DATA_CONNECT_EVENT_NAME.RUN_PROD_MUTATION_WARNING_REJECTED
215+
);
216+
return;
193217
}
194218
}
195219

@@ -237,6 +261,7 @@ export function registerExecution(
237261

238262
// prompt user to continue execution or modify arguments
239263
if (missingArgs.length > 0) {
264+
analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.MISSING_VARIABLES);
240265
// open a modal with option to run anyway or edit args
241266
const editArgs = { title: "Edit variables" };
242267
const continueExecution = { title: "Continue Execution" };
@@ -314,6 +339,7 @@ export function registerExecution(
314339
}
315340

316341
async function generateOperation(arg: GenerateOperationInput) {
342+
analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.GENERATE_OPERATION);
317343
if (!arg.projectId) {
318344
vscode.window.showErrorMessage(`Connect a Firebase project to use Gemini in Firebase features.`);
319345
return;
@@ -339,6 +365,7 @@ ${schema}
339365
}
340366

341367
async function showGiFToSModal(projectId: string): Promise<boolean> {
368+
analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.GIF_TOS_MODAL);
342369
const tos = "Terms of Service";
343370
const enable = "Enable";
344371
const result = await vscode.window.showWarningMessage(
@@ -352,15 +379,20 @@ ${schema}
352379
);
353380
switch (result) {
354381
case enable:
382+
analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.GIF_TOS_MODAL_ACKED);
355383
configstore.set("gemini", true);
356384
await ensureGIFApiTos(projectId);
357385
return true;
358386
case tos:
387+
analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.GIF_TOS_MODAL_CLICKED);
359388
vscode.env.openExternal(
360389
vscode.Uri.parse(
361390
"https://firebase.google.com/docs/gemini-in-firebase#how-gemini-in-firebase-uses-your-data",
362391
),
363392
);
393+
default:
394+
analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.GIF_TOS_MODAL_REJECTED);
395+
break;
364396
}
365397
return false;
366398
}
@@ -390,21 +422,12 @@ ${schema}
390422
vscode.commands.registerCommand(
391423
"firebase.dataConnect.executeOperation",
392424
async (ast, location, instanceType: InstanceType) => {
393-
analyticsLogger.logger.logUsage(
394-
instanceType === InstanceType.LOCAL
395-
? DATA_CONNECT_EVENT_NAME.RUN_LOCAL
396-
: DATA_CONNECT_EVENT_NAME.RUN_PROD,
397-
);
398-
await vscode.window.activeTextEditor?.document.save();
399425
await executeOperation(ast, location, instanceType);
400426
},
401427
),
402428
vscode.commands.registerCommand(
403429
"firebase.dataConnect.generateOperation",
404430
async (arg: GenerateOperationInput) => {
405-
analyticsLogger.logger.logUsage(
406-
DATA_CONNECT_EVENT_NAME.GENERATE_OPERATION,
407-
);
408431
await generateOperation(arg);
409432
},
410433
),
@@ -493,14 +516,3 @@ function getDefaultArgs(args: TypedInput[]) {
493516
return acc;
494517
}, {});
495518
}
496-
497-
// converts AST OperationDefinitionNode to a DocumentNode for schema validation
498-
function operationDefinitionToDocument(
499-
operationDefinition: OperationDefinitionNode,
500-
): DocumentNode {
501-
return {
502-
kind: Kind.DOCUMENT,
503-
definitions: [operationDefinition],
504-
loc: operationDefinition.loc,
505-
};
506-
}

firebase-vscode/src/data-connect/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ export function registerFdc(
155155
dataConnectToolkit,
156156
emulatorController,
157157
context,
158+
analyticsLogger,
158159
);
159160

160161
// register codelens

firebase-vscode/src/data-connect/service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { Client, ClientResponse } from "../../../src/apiv2";
3030
import { InstanceType } from "./code-lens-provider";
3131
import { pluginLogger } from "../logger-wrapper";
3232
import { DataConnectToolkit } from "./toolkit";
33+
import { AnalyticsLogger, DATA_CONNECT_EVENT_NAME } from "../analytics";
3334

3435
/**
3536
* DataConnect Emulator service
@@ -40,6 +41,7 @@ export class DataConnectService {
4041
private dataConnectToolkit: DataConnectToolkit,
4142
private emulatorsController: EmulatorsController,
4243
private context: ExtensionContext,
44+
private analyticsLogger: AnalyticsLogger,
4345
) {}
4446

4547
async servicePath(path: string): Promise<string> {
@@ -56,6 +58,7 @@ export class DataConnectService {
5658
private async handleProdResponse(
5759
response: ClientResponse<GraphqlResponse | GraphqlResponseError>,
5860
): Promise<ExecutionResult> {
61+
this.analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.RUN_PROD + `_${response.status}`);
5962
if (!(response.status >= 200 && response.status < 300)) {
6063
const errorResponse = response as ClientResponse<GraphqlResponseError>;
6164
throw new DataConnectError(
@@ -69,6 +72,7 @@ export class DataConnectService {
6972
private async handleEmulatorResponse(
7073
response: ClientResponse<GraphqlResponse | GraphqlResponseError>,
7174
): Promise<ExecutionResult> {
75+
this.analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.RUN_LOCAL + `_${response.status}`);
7276
if (!(response.status >= 200 && response.status < 300)) {
7377
const errorResponse = response as ClientResponse<GraphqlResponseError>;
7478
throw new DataConnectError(

firebase-vscode/src/data-connect/terminal.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ export function registerTerminalTasks(
102102
if (settings.exportOnExit) {
103103
cmd += ` --export-on-exit ${settings.exportPath}`;
104104
}
105-
vscode.window.showInformationMessage("Starting emulators... Please see terminal.");
106105
runTerminalTask(
107106
"firebase emulators",
108107
cmd,

0 commit comments

Comments
 (0)