Clearcut logging - initial implementation (#1274)

Flag-guarded initial implementation of a clearcut logger to collect telemetry data and send it to Concord for dashboards, etc.
This commit is contained in:
owenofbrien
2025-06-22 09:26:48 -05:00
committed by GitHub
parent c9950b3cb2
commit 4cfab0a893
23 changed files with 1051 additions and 335 deletions

View File

@@ -33,8 +33,10 @@ import {
DEFAULT_TELEMETRY_TARGET,
DEFAULT_OTLP_ENDPOINT,
TelemetryTarget,
StartSessionEvent,
} from '../telemetry/index.js';
import { DEFAULT_GEMINI_EMBEDDING_MODEL } from './models.js';
import { ClearcutLogger } from '../telemetry/clearcut-logger/clearcut-logger.js';
export enum ApprovalMode {
DEFAULT = 'default',
@@ -55,6 +57,7 @@ export interface TelemetrySettings {
target?: TelemetryTarget;
otlpEndpoint?: string;
logPrompts?: boolean;
disableDataCollection?: boolean;
}
export class MCPServerConfig {
@@ -114,6 +117,7 @@ export interface ConfigParameters {
fileDiscoveryService?: FileDiscoveryService;
bugCommand?: BugCommandSettings;
model: string;
disableDataCollection?: boolean;
}
export class Config {
@@ -150,6 +154,7 @@ export class Config {
private readonly cwd: string;
private readonly bugCommand: BugCommandSettings | undefined;
private readonly model: string;
private readonly disableDataCollection: boolean;
constructor(params: ConfigParameters) {
this.sessionId = params.sessionId;
@@ -189,6 +194,8 @@ export class Config {
this.fileDiscoveryService = params.fileDiscoveryService ?? null;
this.bugCommand = params.bugCommand;
this.model = params.model;
this.disableDataCollection =
params.telemetry?.disableDataCollection ?? true;
if (params.contextFileName) {
setGeminiMdFilename(params.contextFileName);
@@ -197,6 +204,12 @@ export class Config {
if (this.telemetrySettings.enabled) {
initializeTelemetry(this);
}
if (!this.disableDataCollection) {
ClearcutLogger.getInstance(this)?.enqueueLogEvent(
new StartSessionEvent(this),
);
}
}
async refreshAuth(authMethod: AuthType) {
@@ -370,6 +383,10 @@ export class Config {
return this.fileDiscoveryService;
}
getDisableDataCollection(): boolean {
return this.disableDataCollection;
}
async getGitService(): Promise<GitService> {
if (!this.gitService) {
this.gitService = new GitService(this.targetDir);