Refac: Centralize storage file management (#4078)

Co-authored-by: Taylor Mullen <ntaylormullen@google.com>
This commit is contained in:
Yuki Okita
2025-08-20 10:55:47 +09:00
committed by GitHub
parent 1049d38845
commit 21c6480b65
50 changed files with 889 additions and 532 deletions

View File

@@ -22,13 +22,13 @@ import {
TEST_ONLY,
} from './clearcut-logger.js';
import { ConfigParameters } from '../../config/config.js';
import * as userAccount from '../../utils/user_account.js';
import * as userId from '../../utils/user_id.js';
import { EventMetadataKey } from './event-metadata-key.js';
import { makeFakeConfig } from '../../test-utils/config.js';
import { http, HttpResponse } from 'msw';
import { server } from '../../mocks/msw.js';
import { makeChatCompressionEvent } from '../types.js';
import { UserAccountManager } from '../../utils/userAccountManager.js';
import { InstallationManager } from '../../utils/installationManager.js';
interface CustomMatchers<R = unknown> {
toHaveMetadataValue: ([key, value]: [EventMetadataKey, string]) => R;
@@ -71,11 +71,11 @@ expect.extend({
},
});
vi.mock('../../utils/user_account');
vi.mock('../../utils/user_id');
vi.mock('../../utils/userAccountManager.js');
vi.mock('../../utils/installationManager.js');
const mockUserAccount = vi.mocked(userAccount);
const mockUserId = vi.mocked(userId);
const mockUserAccount = vi.mocked(UserAccountManager.prototype);
const mockInstallMgr = vi.mocked(InstallationManager.prototype);
// TODO(richieforeman): Consider moving this to test setup globally.
beforeAll(() => {
@@ -113,7 +113,6 @@ describe('ClearcutLogger', () => {
config = {} as Partial<ConfigParameters>,
lifetimeGoogleAccounts = 1,
cachedGoogleAccount = 'test@google.com',
installationId = 'test-installation-id',
} = {}) {
server.resetHandlers(
http.post(CLEARCUT_URL, () => HttpResponse.text(EXAMPLE_RESPONSE)),
@@ -131,7 +130,9 @@ describe('ClearcutLogger', () => {
mockUserAccount.getLifetimeGoogleAccounts.mockReturnValue(
lifetimeGoogleAccounts,
);
mockUserId.getInstallationId.mockReturnValue(installationId);
mockInstallMgr.getInstallationId = vi
.fn()
.mockReturnValue('test-installation-id');
const logger = ClearcutLogger.getInstance(loggerConfig);

View File

@@ -22,12 +22,9 @@ import {
} from '../types.js';
import { EventMetadataKey } from './event-metadata-key.js';
import { Config } from '../../config/config.js';
import { InstallationManager } from '../../utils/installationManager.js';
import { UserAccountManager } from '../../utils/userAccountManager.js';
import { safeJsonStringify } from '../../utils/safeJsonStringify.js';
import {
getCachedGoogleAccount,
getLifetimeGoogleAccounts,
} from '../../utils/user_account.js';
import { getInstallationId } from '../../utils/user_id.js';
import { FixedDeque } from 'mnemonist';
import { GIT_COMMIT_INFO, CLI_VERSION } from '../../generated/git-commit.js';
import { DetectedIde, detectIde } from '../../ide/detect-ide.js';
@@ -129,6 +126,8 @@ export class ClearcutLogger {
private config?: Config;
private sessionData: EventValue[] = [];
private promptId: string = '';
private readonly installationManager: InstallationManager;
private readonly userAccountManager: UserAccountManager;
/**
* Queue of pending events that need to be flushed to the server. New events
@@ -152,10 +151,12 @@ export class ClearcutLogger {
*/
private pendingFlush: boolean = false;
private constructor(config?: Config) {
private constructor(config: Config) {
this.config = config;
this.events = new FixedDeque<LogEventEntry[]>(Array, MAX_EVENTS);
this.promptId = config?.getSessionId() ?? '';
this.installationManager = new InstallationManager();
this.userAccountManager = new UserAccountManager();
}
static getInstance(config?: Config): ClearcutLogger | undefined {
@@ -202,12 +203,14 @@ export class ClearcutLogger {
}
createLogEvent(eventName: EventNames, data: EventValue[] = []): LogEvent {
const email = getCachedGoogleAccount();
const email = this.userAccountManager.getCachedGoogleAccount();
if (eventName !== EventNames.START_SESSION) {
data.push(...this.sessionData);
}
data = this.addDefaultFields(data);
const totalAccounts = this.userAccountManager.getLifetimeGoogleAccounts();
data = this.addDefaultFields(data, totalAccounts);
const logEvent: LogEvent = {
console_type: 'GEMINI_CLI',
@@ -220,7 +223,7 @@ export class ClearcutLogger {
if (email) {
logEvent.client_email = email;
} else {
logEvent.client_install_id = getInstallationId();
logEvent.client_install_id = this.installationManager.getInstallationId();
}
return logEvent;
@@ -679,8 +682,7 @@ export class ClearcutLogger {
* Adds default fields to data, and returns a new data array. This fields
* should exist on all log events.
*/
addDefaultFields(data: EventValue[]): EventValue[] {
const totalAccounts = getLifetimeGoogleAccounts();
addDefaultFields(data: EventValue[], totalAccounts: number): EventValue[] {
const surface = determineSurface();
const defaultLogMetadata: EventValue[] = [