فهرست منبع

feat: add webview memory usage telemetry

Introduces a new telemetry event `WEBVIEW_MEMORY_USAGE` to track memory metrics (heapUsed, heapTotal) from the webview.

- Adds `WEBVIEW_MEMORY_USAGE` to `TelemetryEventName` enum.
- Defines `MemoryMetrics` interface for memory details.
- Integrates `MemoryService` into `App.tsx` to start and stop memory tracking.
- Updates `PostHogTelemetryClient.test.ts` to include `exception` in expected properties when `getTelemetryProperties` fails.
Chris Hasson 6 ماه پیش
والد
کامیت
56e7367d8c

+ 4 - 1
packages/telemetry/src/__tests__/PostHogTelemetryClient.test.ts

@@ -202,7 +202,10 @@ describe("PostHogTelemetryClient", () => {
 				properties: { customProp: "value" },
 			})
 
-			expect(result).toEqual({ customProp: "value" })
+			expect(result).toEqual({
+				customProp: "value",
+				exception: expect.stringContaining("Error: Provider error"),
+			})
 			expect(consoleErrorSpy).toHaveBeenCalledWith(
 				expect.stringContaining("Error getting telemetry properties: Provider error"),
 			)

+ 9 - 0
packages/types/src/telemetry.ts

@@ -27,6 +27,7 @@ export enum TelemetryEventName {
 	CHECKPOINT_FAILURE = "Checkpoint Failure",
 	EXCESSIVE_RECURSION = "Excessive Recursion",
 	NOTIFICATION_CLICKED = "Notification Clicked",
+	WEBVIEW_MEMORY_USAGE = "Webview Memory Usage",
 	// kilocode_change end
 
 	TASK_CREATED = "Task Created",
@@ -148,6 +149,7 @@ export const rooCodeTelemetryEventSchema = z.discriminatedUnion("type", [
 			TelemetryEventName.INLINE_ASSIST_AUTO_TASK,
 			TelemetryEventName.INLINE_ASSIST_ACCEPT_SUGGESTION,
 			TelemetryEventName.INLINE_ASSIST_REJECT_SUGGESTION,
+			TelemetryEventName.WEBVIEW_MEMORY_USAGE,
 			// kilocode_change end
 			TelemetryEventName.TASK_CREATED,
 			TelemetryEventName.TASK_RESTARTED,
@@ -211,6 +213,13 @@ export const rooCodeTelemetryEventSchema = z.discriminatedUnion("type", [
 
 export type RooCodeTelemetryEvent = z.infer<typeof rooCodeTelemetryEventSchema>
 
+// kilocode_change start
+export interface MemoryMetrics {
+	heapUsed: number
+	heapTotal: number
+}
+// kilocode_change end
+
 /**
  * TelemetryEventSubscription
  */

+ 5 - 0
webview-ui/src/App.tsx

@@ -28,6 +28,7 @@ import { useAddNonInteractiveClickListener } from "./components/ui/hooks/useNonI
 import { TooltipProvider } from "./components/ui/tooltip"
 import { STANDARD_TOOLTIP_DELAY } from "./components/ui/standard-tooltip"
 import { useKiloIdentity } from "./utils/kilocode/useKiloIdentity"
+import { MemoryService } from "./services/MemoryService"
 
 type Tab = "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account" | "profile" // kilocode_change: add "profile"
 
@@ -204,6 +205,10 @@ const App = () => {
 	useEffect(() => {
 		if (didHydrateState) {
 			telemetryClient.updateTelemetryState(telemetrySetting, telemetryKey, telemetryDistinctId)
+
+			const memoryService = new MemoryService()
+			memoryService.start()
+			return () => memoryService.stop()
 		}
 	}, [telemetrySetting, telemetryKey, telemetryDistinctId, didHydrateState])
 	// kilocode_change end

+ 50 - 0
webview-ui/src/services/MemoryService.ts

@@ -0,0 +1,50 @@
+// kilocode_change - new file
+import { telemetryClient } from "../utils/TelemetryClient"
+import { TelemetryEventName, type MemoryMetrics } from "@roo-code/types"
+
+export class MemoryService {
+	private intervalId: number | null = null
+	private readonly intervalMs: number = 60 * 1000
+
+	public start(): void {
+		if (this.intervalId) {
+			return
+		}
+		this.reportMemoryUsage()
+
+		this.intervalId = window.setInterval(() => {
+			this.reportMemoryUsage()
+		}, this.intervalMs)
+	}
+
+	public stop(): void {
+		if (this.intervalId) {
+			window.clearInterval(this.intervalId)
+			this.intervalId = null
+		}
+	}
+
+	private reportMemoryUsage(): void {
+		const memoryInfo = this.getMemoryInfo()
+		telemetryClient.capture(TelemetryEventName.WEBVIEW_MEMORY_USAGE, memoryInfo)
+	}
+
+	private getMemoryInfo(): MemoryMetrics {
+		const memory = (performance as Performance & { memory?: any }).memory
+		if (!memory) {
+			return {
+				heapUsed: 0,
+				heapTotal: 0,
+			}
+		}
+
+		return {
+			heapUsed: this.bytesToMegabytes(memory.usedJSHeapSize || 0),
+			heapTotal: this.bytesToMegabytes(memory.totalJSHeapSize || 0),
+		}
+	}
+
+	private bytesToMegabytes(bytes: number): number {
+		return Math.round((bytes / 1024 / 1024) * 100) / 100
+	}
+}