mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 12:54:07 -07:00
track github repository names in telemetry events (#13670)
Co-authored-by: riddhi <duttariddhi@google.com>
This commit is contained in:
@@ -427,6 +427,84 @@ describe('ClearcutLogger', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('GITHUB_REPOSITORY metadata', () => {
|
||||||
|
it('includes hashed repository when GITHUB_REPOSITORY is set', () => {
|
||||||
|
vi.stubEnv('GITHUB_REPOSITORY', 'google/gemini-cli');
|
||||||
|
const { logger } = setup({});
|
||||||
|
|
||||||
|
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||||
|
const repositoryMetadata = event?.event_metadata[0].find(
|
||||||
|
(item) =>
|
||||||
|
item.gemini_cli_key ===
|
||||||
|
EventMetadataKey.GEMINI_CLI_GH_REPOSITORY_NAME_HASH,
|
||||||
|
);
|
||||||
|
expect(repositoryMetadata).toBeDefined();
|
||||||
|
expect(repositoryMetadata?.value).toMatch(/^[a-f0-9]{64}$/);
|
||||||
|
expect(repositoryMetadata?.value).not.toBe('google/gemini-cli');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('hashes repository name consistently', () => {
|
||||||
|
vi.stubEnv('GITHUB_REPOSITORY', 'google/gemini-cli');
|
||||||
|
const { logger } = setup({});
|
||||||
|
|
||||||
|
const event1 = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||||
|
const event2 = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||||
|
|
||||||
|
const hash1 = event1?.event_metadata[0].find(
|
||||||
|
(item) =>
|
||||||
|
item.gemini_cli_key ===
|
||||||
|
EventMetadataKey.GEMINI_CLI_GH_REPOSITORY_NAME_HASH,
|
||||||
|
)?.value;
|
||||||
|
const hash2 = event2?.event_metadata[0].find(
|
||||||
|
(item) =>
|
||||||
|
item.gemini_cli_key ===
|
||||||
|
EventMetadataKey.GEMINI_CLI_GH_REPOSITORY_NAME_HASH,
|
||||||
|
)?.value;
|
||||||
|
|
||||||
|
expect(hash1).toBeDefined();
|
||||||
|
expect(hash2).toBeDefined();
|
||||||
|
expect(hash1).toBe(hash2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('produces different hashes for different repositories', () => {
|
||||||
|
vi.stubEnv('GITHUB_REPOSITORY', 'google/gemini-cli');
|
||||||
|
const { logger: logger1 } = setup({});
|
||||||
|
const event1 = logger1?.createLogEvent(EventNames.API_ERROR, []);
|
||||||
|
const hash1 = event1?.event_metadata[0].find(
|
||||||
|
(item) =>
|
||||||
|
item.gemini_cli_key ===
|
||||||
|
EventMetadataKey.GEMINI_CLI_GH_REPOSITORY_NAME_HASH,
|
||||||
|
)?.value;
|
||||||
|
|
||||||
|
vi.stubEnv('GITHUB_REPOSITORY', 'google/other-repo');
|
||||||
|
ClearcutLogger.clearInstance();
|
||||||
|
const { logger: logger2 } = setup({});
|
||||||
|
const event2 = logger2?.createLogEvent(EventNames.API_ERROR, []);
|
||||||
|
const hash2 = event2?.event_metadata[0].find(
|
||||||
|
(item) =>
|
||||||
|
item.gemini_cli_key ===
|
||||||
|
EventMetadataKey.GEMINI_CLI_GH_REPOSITORY_NAME_HASH,
|
||||||
|
)?.value;
|
||||||
|
|
||||||
|
expect(hash1).toBeDefined();
|
||||||
|
expect(hash2).toBeDefined();
|
||||||
|
expect(hash1).not.toBe(hash2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not include repository when GITHUB_REPOSITORY is not set', () => {
|
||||||
|
vi.stubEnv('GITHUB_REPOSITORY', undefined);
|
||||||
|
const { logger } = setup({});
|
||||||
|
|
||||||
|
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||||
|
const hasRepository = event?.event_metadata[0].some(
|
||||||
|
(item) =>
|
||||||
|
item.gemini_cli_key ===
|
||||||
|
EventMetadataKey.GEMINI_CLI_GH_REPOSITORY_NAME_HASH,
|
||||||
|
);
|
||||||
|
expect(hasRepository).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('logChatCompressionEvent', () => {
|
describe('logChatCompressionEvent', () => {
|
||||||
it('logs an event with proper fields', () => {
|
it('logs an event with proper fields', () => {
|
||||||
const { logger } = setup();
|
const { logger } = setup();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { createHash } from 'node:crypto';
|
||||||
import { HttpsProxyAgent } from 'https-proxy-agent';
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
||||||
import type {
|
import type {
|
||||||
StartSessionEvent,
|
StartSessionEvent,
|
||||||
@@ -155,6 +156,13 @@ function determineGHWorkflowName(): string | undefined {
|
|||||||
return process.env['GH_WORKFLOW_NAME'];
|
return process.env['GH_WORKFLOW_NAME'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the GitHub repository name if the CLI is running in a GitHub Actions environment.
|
||||||
|
*/
|
||||||
|
function determineGHRepositoryName(): string | undefined {
|
||||||
|
return process.env['GITHUB_REPOSITORY'];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clearcut URL to send logging events to.
|
* Clearcut URL to send logging events to.
|
||||||
*/
|
*/
|
||||||
@@ -186,6 +194,7 @@ export class ClearcutLogger {
|
|||||||
private promptId: string = '';
|
private promptId: string = '';
|
||||||
private readonly installationManager: InstallationManager;
|
private readonly installationManager: InstallationManager;
|
||||||
private readonly userAccountManager: UserAccountManager;
|
private readonly userAccountManager: UserAccountManager;
|
||||||
|
private readonly hashedGHRepositoryName?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue of pending events that need to be flushed to the server. New events
|
* Queue of pending events that need to be flushed to the server. New events
|
||||||
@@ -215,6 +224,13 @@ export class ClearcutLogger {
|
|||||||
this.promptId = config?.getSessionId() ?? '';
|
this.promptId = config?.getSessionId() ?? '';
|
||||||
this.installationManager = new InstallationManager();
|
this.installationManager = new InstallationManager();
|
||||||
this.userAccountManager = new UserAccountManager();
|
this.userAccountManager = new UserAccountManager();
|
||||||
|
|
||||||
|
const ghRepositoryName = determineGHRepositoryName();
|
||||||
|
if (ghRepositoryName) {
|
||||||
|
this.hashedGHRepositoryName = createHash('sha256')
|
||||||
|
.update(ghRepositoryName)
|
||||||
|
.digest('hex');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getInstance(config?: Config): ClearcutLogger | undefined {
|
static getInstance(config?: Config): ClearcutLogger | undefined {
|
||||||
@@ -323,6 +339,13 @@ export class ClearcutLogger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.hashedGHRepositoryName) {
|
||||||
|
baseMetadata.push({
|
||||||
|
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_REPOSITORY_NAME_HASH,
|
||||||
|
value: this.hashedGHRepositoryName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const logEvent: LogEvent = {
|
const logEvent: LogEvent = {
|
||||||
console_type: 'GEMINI_CLI',
|
console_type: 'GEMINI_CLI',
|
||||||
application: 102, // GEMINI_CLI
|
application: 102, // GEMINI_CLI
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
// Defines valid event metadata keys for Clearcut logging.
|
// Defines valid event metadata keys for Clearcut logging.
|
||||||
export enum EventMetadataKey {
|
export enum EventMetadataKey {
|
||||||
// Deleted enums: 24
|
// Deleted enums: 24
|
||||||
// Next ID: 131
|
// Next ID: 133
|
||||||
|
|
||||||
GEMINI_CLI_KEY_UNKNOWN = 0,
|
GEMINI_CLI_KEY_UNKNOWN = 0,
|
||||||
|
|
||||||
@@ -197,6 +197,9 @@ export enum EventMetadataKey {
|
|||||||
// Logs the active experiment IDs for the session.
|
// Logs the active experiment IDs for the session.
|
||||||
GEMINI_CLI_EXPERIMENT_IDS = 131,
|
GEMINI_CLI_EXPERIMENT_IDS = 131,
|
||||||
|
|
||||||
|
// Logs the repository name of the GitHub Action that triggered the session.
|
||||||
|
GEMINI_CLI_GH_REPOSITORY_NAME_HASH = 132,
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Loop Detected Event Keys
|
// Loop Detected Event Keys
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user