feat(telemetry) - Add metric for slow rendering (#12391)

Co-authored-by: gemini-cli-robot <gemini-cli-robot@google.com>
This commit is contained in:
shishu314
2025-10-31 14:57:47 -04:00
committed by GitHub
parent e9c7a80b12
commit 35f091bb01
3 changed files with 42 additions and 0 deletions

View File

@@ -126,6 +126,7 @@ export {
recordBaselineComparison,
isPerformanceMonitoringActive,
recordFlickerFrame,
recordSlowRender,
// Performance monitoring types
PerformanceMetricType,
MemoryMetricType,

View File

@@ -95,6 +95,7 @@ describe('Telemetry Metrics', () => {
let recordExitFailModule: typeof import('./metrics.js').recordExitFail;
let recordAgentRunMetricsModule: typeof import('./metrics.js').recordAgentRunMetrics;
let recordLinesChangedModule: typeof import('./metrics.js').recordLinesChanged;
let recordSlowRenderModule: typeof import('./metrics.js').recordSlowRender;
beforeEach(async () => {
vi.resetModules();
@@ -138,6 +139,7 @@ describe('Telemetry Metrics', () => {
recordExitFailModule = metricsJsModule.recordExitFail;
recordAgentRunMetricsModule = metricsJsModule.recordAgentRunMetrics;
recordLinesChangedModule = metricsJsModule.recordLinesChanged;
recordSlowRenderModule = metricsJsModule.recordSlowRender;
const otelApiModule = await import('@opentelemetry/api');
@@ -196,6 +198,26 @@ describe('Telemetry Metrics', () => {
});
});
describe('recordSlowRender', () => {
it('does not record metrics if not initialized', () => {
const config = makeFakeConfig({});
recordSlowRenderModule(config, 123);
expect(mockHistogramRecordFn).not.toHaveBeenCalled();
});
it('records a slow render event when initialized', () => {
const config = makeFakeConfig({});
initializeMetricsModule(config);
recordSlowRenderModule(config, 123);
expect(mockHistogramRecordFn).toHaveBeenCalledWith(123, {
'session.id': 'test-session-id',
'installation.id': 'test-installation-id',
'user.email': 'test@example.com',
});
});
});
describe('initializeMetrics', () => {
const mockConfig = {
getSessionId: () => 'test-session-id',

View File

@@ -57,6 +57,7 @@ const REGRESSION_PERCENTAGE_CHANGE =
'gemini_cli.performance.regression.percentage_change';
const BASELINE_COMPARISON = 'gemini_cli.performance.baseline.comparison';
const FLICKER_FRAME_COUNT = 'gemini_cli.ui.flicker.count';
const SLOW_RENDER_LATENCY = 'gemini_cli.ui.slow_render.latency';
const EXIT_FAIL_COUNT = 'gemini_cli.exit.fail.count';
const baseMetricDefinition = {
@@ -227,6 +228,13 @@ const HISTOGRAM_DEFINITIONS = {
agent_name: string;
},
},
[SLOW_RENDER_LATENCY]: {
description: 'Counts UI frames that take too long to render.',
unit: 'ms',
valueType: ValueType.INT,
assign: (h: Histogram) => (slowRenderHistogram = h),
attributes: {} as Record<string, never>,
},
[AGENT_TURNS]: {
description: 'Number of turns taken by agents.',
unit: 'turns',
@@ -472,6 +480,7 @@ let agentDurationHistogram: Histogram | undefined;
let agentTurnsHistogram: Histogram | undefined;
let flickerFrameCounter: Counter | undefined;
let exitFailCounter: Counter | undefined;
let slowRenderHistogram: Histogram | undefined;
// OpenTelemetry GenAI Semantic Convention Metrics
let genAiClientTokenUsageHistogram: Histogram | undefined;
@@ -660,6 +669,16 @@ export function recordExitFail(config: Config): void {
exitFailCounter.add(1, baseMetricDefinition.getCommonAttributes(config));
}
/**
* Records a metric for when a UI frame is slow in rendering
*/
export function recordSlowRender(config: Config, renderLatency: number): void {
if (!slowRenderHistogram || !isMetricsInitialized) return;
slowRenderHistogram.record(renderLatency, {
...baseMetricDefinition.getCommonAttributes(config),
});
}
/**
* Records a metric for when an invalid chunk is received from a stream.
*/