2025-06-05 16:04:25 -04:00
|
|
|
/**
|
|
|
|
|
* @license
|
|
|
|
|
* Copyright 2025 Google LLC
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*/
|
|
|
|
|
|
2025-10-09 16:02:58 -07:00
|
|
|
import type { LogRecord } from '@opentelemetry/api-logs';
|
2025-08-26 00:04:53 +02:00
|
|
|
import { logs } from '@opentelemetry/api-logs';
|
|
|
|
|
import type { Config } from '../config/config.js';
|
2025-10-09 16:02:58 -07:00
|
|
|
import { SERVICE_NAME } from './constants.js';
|
2025-06-05 16:04:25 -04:00
|
|
|
import {
|
|
|
|
|
EVENT_API_ERROR,
|
|
|
|
|
EVENT_API_RESPONSE,
|
|
|
|
|
EVENT_TOOL_CALL,
|
2026-02-03 16:17:29 -05:00
|
|
|
EVENT_REWIND,
|
2025-10-09 16:02:58 -07:00
|
|
|
} from './types.js';
|
2025-08-26 00:04:53 +02:00
|
|
|
import type {
|
2025-06-05 16:04:25 -04:00
|
|
|
ApiErrorEvent,
|
|
|
|
|
ApiRequestEvent,
|
|
|
|
|
ApiResponseEvent,
|
2025-08-22 17:47:32 +05:30
|
|
|
FileOperationEvent,
|
2025-08-05 18:52:58 -04:00
|
|
|
IdeConnectionEvent,
|
2025-06-22 09:26:48 -05:00
|
|
|
StartSessionEvent,
|
2025-06-05 16:04:25 -04:00
|
|
|
ToolCallEvent,
|
|
|
|
|
UserPromptEvent,
|
2025-07-12 02:40:25 +05:30
|
|
|
FlashFallbackEvent,
|
2025-07-30 21:47:04 -07:00
|
|
|
NextSpeakerCheckEvent,
|
2025-07-14 21:44:07 -07:00
|
|
|
LoopDetectedEvent,
|
2025-09-15 14:12:39 -07:00
|
|
|
LoopDetectionDisabledEvent,
|
2025-07-29 16:20:37 -04:00
|
|
|
SlashCommandEvent,
|
2026-02-03 16:17:29 -05:00
|
|
|
RewindEvent,
|
2025-08-25 16:06:47 -04:00
|
|
|
ConversationFinishedEvent,
|
2025-08-18 15:59:13 -04:00
|
|
|
ChatCompressionEvent,
|
2025-08-24 19:11:41 -07:00
|
|
|
MalformedJsonResponseEvent,
|
2025-08-26 15:37:18 -04:00
|
|
|
InvalidChunkEvent,
|
|
|
|
|
ContentRetryEvent,
|
|
|
|
|
ContentRetryFailureEvent,
|
2025-09-08 14:44:56 -07:00
|
|
|
RipgrepFallbackEvent,
|
2025-09-11 08:40:46 -07:00
|
|
|
ToolOutputTruncatedEvent,
|
2025-09-16 16:53:58 -04:00
|
|
|
ModelRoutingEvent,
|
2025-09-23 14:37:35 -04:00
|
|
|
ExtensionDisableEvent,
|
2025-09-18 14:01:36 -04:00
|
|
|
ExtensionEnableEvent,
|
|
|
|
|
ExtensionUninstallEvent,
|
|
|
|
|
ExtensionInstallEvent,
|
2025-09-23 18:06:03 -04:00
|
|
|
ModelSlashCommandEvent,
|
2026-01-05 15:25:54 -05:00
|
|
|
EditStrategyEvent,
|
|
|
|
|
EditCorrectionEvent,
|
2025-10-08 15:42:33 -04:00
|
|
|
AgentStartEvent,
|
|
|
|
|
AgentFinishEvent,
|
2025-11-03 17:53:43 -05:00
|
|
|
RecoveryAttemptEvent,
|
2025-10-09 13:01:17 -04:00
|
|
|
WebFetchFallbackAttemptEvent,
|
2025-10-10 14:28:13 -07:00
|
|
|
ExtensionUpdateEvent,
|
2026-01-20 13:57:34 -05:00
|
|
|
ApprovalModeSwitchEvent,
|
|
|
|
|
ApprovalModeDurationEvent,
|
2025-11-24 13:13:24 -08:00
|
|
|
HookCallEvent,
|
2025-12-08 12:29:50 -08:00
|
|
|
StartupStatsEvent,
|
2026-01-20 13:57:34 -05:00
|
|
|
LlmLoopCheckEvent,
|
2026-02-05 18:46:34 -05:00
|
|
|
PlanExecutionEvent,
|
2026-02-05 20:53:11 -05:00
|
|
|
ToolOutputMaskingEvent,
|
2025-06-05 16:04:25 -04:00
|
|
|
} from './types.js';
|
|
|
|
|
import {
|
|
|
|
|
recordApiErrorMetrics,
|
|
|
|
|
recordToolCallMetrics,
|
2025-08-18 15:59:13 -04:00
|
|
|
recordChatCompressionMetrics,
|
2025-08-22 17:47:32 +05:30
|
|
|
recordFileOperationMetric,
|
2025-08-26 15:37:18 -04:00
|
|
|
recordInvalidChunk,
|
|
|
|
|
recordContentRetry,
|
|
|
|
|
recordContentRetryFailure,
|
2025-09-16 16:53:58 -04:00
|
|
|
recordModelRoutingMetrics,
|
2025-09-23 18:06:03 -04:00
|
|
|
recordModelSlashCommand,
|
2025-10-01 16:24:55 -04:00
|
|
|
getConventionAttributes,
|
|
|
|
|
recordTokenUsageMetrics,
|
|
|
|
|
recordApiResponseMetrics,
|
2025-10-08 15:42:33 -04:00
|
|
|
recordAgentRunMetrics,
|
2025-11-03 17:53:43 -05:00
|
|
|
recordRecoveryAttemptMetrics,
|
2025-10-30 14:55:47 -04:00
|
|
|
recordLinesChanged,
|
2025-11-24 13:13:24 -08:00
|
|
|
recordHookCallMetrics,
|
2026-02-05 18:46:34 -05:00
|
|
|
recordPlanExecution,
|
2025-06-05 16:04:25 -04:00
|
|
|
} from './metrics.js';
|
2025-12-02 21:27:37 -08:00
|
|
|
import { bufferTelemetryEvent } from './sdk.js';
|
2025-08-26 00:04:53 +02:00
|
|
|
import type { UiEvent } from './uiTelemetry.js';
|
|
|
|
|
import { uiTelemetryService } from './uiTelemetry.js';
|
2025-06-22 09:26:48 -05:00
|
|
|
import { ClearcutLogger } from './clearcut-logger/clearcut-logger.js';
|
2025-06-11 16:50:24 +00:00
|
|
|
|
2025-06-22 09:26:48 -05:00
|
|
|
export function logCliConfiguration(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: StartSessionEvent,
|
|
|
|
|
): void {
|
2026-01-12 23:59:22 +00:00
|
|
|
void ClearcutLogger.getInstance(config)?.logStartSessionEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-06-05 16:04:25 -04:00
|
|
|
}
|
|
|
|
|
|
2025-06-22 09:26:48 -05:00
|
|
|
export function logUserPrompt(config: Config, event: UserPromptEvent): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logNewPromptEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-06-05 16:04:25 -04:00
|
|
|
}
|
|
|
|
|
|
2025-06-22 09:26:48 -05:00
|
|
|
export function logToolCall(config: Config, event: ToolCallEvent): void {
|
2025-06-29 20:44:33 -04:00
|
|
|
const uiEvent = {
|
|
|
|
|
...event,
|
|
|
|
|
'event.name': EVENT_TOOL_CALL,
|
|
|
|
|
'event.timestamp': new Date().toISOString(),
|
|
|
|
|
} as UiEvent;
|
|
|
|
|
uiTelemetryService.addEvent(uiEvent);
|
2025-06-22 09:26:48 -05:00
|
|
|
ClearcutLogger.getInstance(config)?.logToolCallEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
recordToolCallMetrics(config, event.duration_ms, {
|
|
|
|
|
function_name: event.function_name,
|
|
|
|
|
success: event.success,
|
|
|
|
|
decision: event.decision,
|
|
|
|
|
tool_type: event.tool_type,
|
|
|
|
|
});
|
2025-06-12 16:48:10 -04:00
|
|
|
|
2025-12-02 21:27:37 -08:00
|
|
|
if (event.metadata) {
|
|
|
|
|
const added = event.metadata['model_added_lines'];
|
|
|
|
|
if (typeof added === 'number' && added > 0) {
|
|
|
|
|
recordLinesChanged(config, added, 'added', {
|
|
|
|
|
function_name: event.function_name,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
const removed = event.metadata['model_removed_lines'];
|
|
|
|
|
if (typeof removed === 'number' && removed > 0) {
|
|
|
|
|
recordLinesChanged(config, removed, 'removed', {
|
|
|
|
|
function_name: event.function_name,
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-10-30 14:55:47 -04:00
|
|
|
}
|
2025-12-02 21:27:37 -08:00
|
|
|
});
|
2025-06-05 16:04:25 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-11 08:40:46 -07:00
|
|
|
export function logToolOutputTruncated(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ToolOutputTruncatedEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logToolOutputTruncatedEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-09-11 08:40:46 -07:00
|
|
|
}
|
|
|
|
|
|
2026-02-05 20:53:11 -05:00
|
|
|
export function logToolOutputMasking(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ToolOutputMaskingEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logToolOutputMaskingEvent(event);
|
|
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-22 17:47:32 +05:30
|
|
|
export function logFileOperation(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: FileOperationEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logFileOperationEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
|
|
|
|
|
recordFileOperationMetric(config, {
|
|
|
|
|
operation: event.operation,
|
|
|
|
|
lines: event.lines,
|
|
|
|
|
mimetype: event.mimetype,
|
|
|
|
|
extension: event.extension,
|
|
|
|
|
programming_language: event.programming_language,
|
|
|
|
|
});
|
2025-10-01 06:33:47 -07:00
|
|
|
});
|
2025-08-22 17:47:32 +05:30
|
|
|
}
|
|
|
|
|
|
2025-06-22 09:26:48 -05:00
|
|
|
export function logApiRequest(config: Config, event: ApiRequestEvent): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logApiRequestEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
logger.emit(event.toLogRecord(config));
|
|
|
|
|
logger.emit(event.toSemanticLogRecord(config));
|
|
|
|
|
});
|
2025-06-05 16:04:25 -04:00
|
|
|
}
|
|
|
|
|
|
2025-07-12 02:40:25 +05:30
|
|
|
export function logFlashFallback(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: FlashFallbackEvent,
|
|
|
|
|
): void {
|
2025-08-19 15:06:00 -05:00
|
|
|
ClearcutLogger.getInstance(config)?.logFlashFallbackEvent();
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-07-12 02:40:25 +05:30
|
|
|
}
|
|
|
|
|
|
2025-09-08 14:44:56 -07:00
|
|
|
export function logRipgrepFallback(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: RipgrepFallbackEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logRipgrepFallbackEvent();
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-09-08 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
|
2025-06-22 09:26:48 -05:00
|
|
|
export function logApiError(config: Config, event: ApiErrorEvent): void {
|
2025-06-29 20:44:33 -04:00
|
|
|
const uiEvent = {
|
|
|
|
|
...event,
|
|
|
|
|
'event.name': EVENT_API_ERROR,
|
|
|
|
|
'event.timestamp': new Date().toISOString(),
|
|
|
|
|
} as UiEvent;
|
|
|
|
|
uiTelemetryService.addEvent(uiEvent);
|
2025-06-22 09:26:48 -05:00
|
|
|
ClearcutLogger.getInstance(config)?.logApiErrorEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
logger.emit(event.toLogRecord(config));
|
|
|
|
|
logger.emit(event.toSemanticLogRecord(config));
|
2025-10-28 13:02:46 -07:00
|
|
|
|
2025-12-02 21:27:37 -08:00
|
|
|
recordApiErrorMetrics(config, event.duration_ms, {
|
|
|
|
|
model: event.model,
|
|
|
|
|
status_code: event.status_code,
|
|
|
|
|
error_type: event.error_type,
|
|
|
|
|
});
|
2025-10-01 16:24:55 -04:00
|
|
|
|
2025-12-02 21:27:37 -08:00
|
|
|
// Record GenAI operation duration for errors
|
|
|
|
|
recordApiResponseMetrics(config, event.duration_ms, {
|
|
|
|
|
model: event.model,
|
|
|
|
|
status_code: event.status_code,
|
|
|
|
|
genAiAttributes: {
|
|
|
|
|
...getConventionAttributes(event),
|
|
|
|
|
'error.type': event.error_type || 'unknown',
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-10-01 16:24:55 -04:00
|
|
|
});
|
2025-06-05 16:04:25 -04:00
|
|
|
}
|
|
|
|
|
|
2025-06-22 09:26:48 -05:00
|
|
|
export function logApiResponse(config: Config, event: ApiResponseEvent): void {
|
2025-06-29 20:44:33 -04:00
|
|
|
const uiEvent = {
|
|
|
|
|
...event,
|
|
|
|
|
'event.name': EVENT_API_RESPONSE,
|
|
|
|
|
'event.timestamp': new Date().toISOString(),
|
|
|
|
|
} as UiEvent;
|
|
|
|
|
uiTelemetryService.addEvent(uiEvent);
|
2025-06-22 09:26:48 -05:00
|
|
|
ClearcutLogger.getInstance(config)?.logApiResponseEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
logger.emit(event.toLogRecord(config));
|
|
|
|
|
logger.emit(event.toSemanticLogRecord(config));
|
2025-06-05 16:04:25 -04:00
|
|
|
|
2025-12-02 21:27:37 -08:00
|
|
|
const conventionAttributes = getConventionAttributes(event);
|
2025-10-01 16:24:55 -04:00
|
|
|
|
2025-12-02 21:27:37 -08:00
|
|
|
recordApiResponseMetrics(config, event.duration_ms, {
|
2025-10-01 16:24:55 -04:00
|
|
|
model: event.model,
|
2025-12-02 21:27:37 -08:00
|
|
|
status_code: event.status_code,
|
2025-10-01 16:24:55 -04:00
|
|
|
genAiAttributes: conventionAttributes,
|
|
|
|
|
});
|
2025-12-02 21:27:37 -08:00
|
|
|
|
|
|
|
|
const tokenUsageData = [
|
|
|
|
|
{ count: event.usage.input_token_count, type: 'input' as const },
|
|
|
|
|
{ count: event.usage.output_token_count, type: 'output' as const },
|
|
|
|
|
{ count: event.usage.cached_content_token_count, type: 'cache' as const },
|
|
|
|
|
{ count: event.usage.thoughts_token_count, type: 'thought' as const },
|
|
|
|
|
{ count: event.usage.tool_token_count, type: 'tool' as const },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for (const { count, type } of tokenUsageData) {
|
|
|
|
|
recordTokenUsageMetrics(config, count, {
|
|
|
|
|
model: event.model,
|
|
|
|
|
type,
|
|
|
|
|
genAiAttributes: conventionAttributes,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-06-05 16:04:25 -04:00
|
|
|
}
|
2025-07-14 21:44:07 -07:00
|
|
|
|
|
|
|
|
export function logLoopDetected(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: LoopDetectedEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logLoopDetectedEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-07-14 21:44:07 -07:00
|
|
|
}
|
2025-07-22 18:01:24 -07:00
|
|
|
|
2025-09-15 14:12:39 -07:00
|
|
|
export function logLoopDetectionDisabled(
|
|
|
|
|
config: Config,
|
2025-10-09 16:02:58 -07:00
|
|
|
event: LoopDetectionDisabledEvent,
|
2025-09-15 14:12:39 -07:00
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logLoopDetectionDisabledEvent();
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-09-15 14:12:39 -07:00
|
|
|
}
|
|
|
|
|
|
2025-07-30 21:47:04 -07:00
|
|
|
export function logNextSpeakerCheck(
|
2025-07-22 18:01:24 -07:00
|
|
|
config: Config,
|
2025-07-30 21:47:04 -07:00
|
|
|
event: NextSpeakerCheckEvent,
|
2025-07-22 18:01:24 -07:00
|
|
|
): void {
|
2025-07-30 21:47:04 -07:00
|
|
|
ClearcutLogger.getInstance(config)?.logNextSpeakerCheck(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-07-22 18:01:24 -07:00
|
|
|
}
|
2025-07-29 16:20:37 -04:00
|
|
|
|
|
|
|
|
export function logSlashCommand(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: SlashCommandEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logSlashCommandEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-07-29 16:20:37 -04:00
|
|
|
}
|
2025-08-05 18:52:58 -04:00
|
|
|
|
2026-02-03 16:17:29 -05:00
|
|
|
export function logRewind(config: Config, event: RewindEvent): void {
|
|
|
|
|
const uiEvent = {
|
|
|
|
|
...event,
|
|
|
|
|
'event.name': EVENT_REWIND,
|
|
|
|
|
'event.timestamp': new Date().toISOString(),
|
|
|
|
|
} as UiEvent;
|
|
|
|
|
uiTelemetryService.addEvent(uiEvent);
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logRewindEvent(event);
|
|
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-05 18:52:58 -04:00
|
|
|
export function logIdeConnection(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: IdeConnectionEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logIdeConnectionEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-08-05 18:52:58 -04:00
|
|
|
}
|
2025-08-13 13:32:54 -04:00
|
|
|
|
2025-08-25 16:06:47 -04:00
|
|
|
export function logConversationFinishedEvent(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ConversationFinishedEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logConversationFinishedEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-08-25 16:06:47 -04:00
|
|
|
}
|
|
|
|
|
|
2025-08-18 15:59:13 -04:00
|
|
|
export function logChatCompression(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ChatCompressionEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logChatCompressionEvent(event);
|
|
|
|
|
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
2025-10-09 16:02:58 -07:00
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
2025-08-18 15:59:13 -04:00
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
|
|
|
|
|
recordChatCompressionMetrics(config, {
|
|
|
|
|
tokens_before: event.tokens_before,
|
|
|
|
|
tokens_after: event.tokens_after,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-24 19:11:41 -07:00
|
|
|
export function logMalformedJsonResponse(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: MalformedJsonResponseEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logMalformedJsonResponseEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-08-24 19:11:41 -07:00
|
|
|
}
|
2025-08-26 15:37:18 -04:00
|
|
|
|
|
|
|
|
export function logInvalidChunk(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: InvalidChunkEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logInvalidChunkEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
recordInvalidChunk(config);
|
|
|
|
|
});
|
2025-08-26 15:37:18 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function logContentRetry(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ContentRetryEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logContentRetryEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
recordContentRetry(config);
|
|
|
|
|
});
|
2025-08-26 15:37:18 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function logContentRetryFailure(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ContentRetryFailureEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logContentRetryFailureEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
recordContentRetryFailure(config);
|
|
|
|
|
});
|
2025-08-26 15:37:18 -04:00
|
|
|
}
|
2025-09-16 16:53:58 -04:00
|
|
|
|
|
|
|
|
export function logModelRouting(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ModelRoutingEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logModelRoutingEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
recordModelRoutingMetrics(config, event);
|
|
|
|
|
});
|
2025-09-16 16:53:58 -04:00
|
|
|
}
|
2025-09-18 14:01:36 -04:00
|
|
|
|
2025-09-23 18:06:03 -04:00
|
|
|
export function logModelSlashCommand(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ModelSlashCommandEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logModelSlashCommandEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
recordModelSlashCommand(config, event);
|
|
|
|
|
});
|
2025-09-23 18:06:03 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-08 10:29:36 -05:00
|
|
|
export async function logExtensionInstallEvent(
|
2025-09-18 14:01:36 -04:00
|
|
|
config: Config,
|
|
|
|
|
event: ExtensionInstallEvent,
|
2025-11-08 10:29:36 -05:00
|
|
|
): Promise<void> {
|
|
|
|
|
await ClearcutLogger.getInstance(config)?.logExtensionInstallEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-09-18 14:01:36 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-08 10:29:36 -05:00
|
|
|
export async function logExtensionUninstall(
|
2025-09-18 14:01:36 -04:00
|
|
|
config: Config,
|
|
|
|
|
event: ExtensionUninstallEvent,
|
2025-11-08 10:29:36 -05:00
|
|
|
): Promise<void> {
|
|
|
|
|
await ClearcutLogger.getInstance(config)?.logExtensionUninstallEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-10-10 14:28:13 -07:00
|
|
|
}
|
|
|
|
|
|
2025-11-08 10:29:36 -05:00
|
|
|
export async function logExtensionUpdateEvent(
|
2025-10-10 14:28:13 -07:00
|
|
|
config: Config,
|
|
|
|
|
event: ExtensionUpdateEvent,
|
2025-11-08 10:29:36 -05:00
|
|
|
): Promise<void> {
|
|
|
|
|
await ClearcutLogger.getInstance(config)?.logExtensionUpdateEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-09-18 14:01:36 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-08 10:29:36 -05:00
|
|
|
export async function logExtensionEnable(
|
2025-09-18 14:01:36 -04:00
|
|
|
config: Config,
|
|
|
|
|
event: ExtensionEnableEvent,
|
2025-11-08 10:29:36 -05:00
|
|
|
): Promise<void> {
|
|
|
|
|
await ClearcutLogger.getInstance(config)?.logExtensionEnableEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-09-18 14:01:36 -04:00
|
|
|
}
|
2025-09-23 14:37:35 -04:00
|
|
|
|
2025-11-08 10:29:36 -05:00
|
|
|
export async function logExtensionDisable(
|
2025-09-23 14:37:35 -04:00
|
|
|
config: Config,
|
|
|
|
|
event: ExtensionDisableEvent,
|
2025-11-08 10:29:36 -05:00
|
|
|
): Promise<void> {
|
|
|
|
|
await ClearcutLogger.getInstance(config)?.logExtensionDisableEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-09-23 14:37:35 -04:00
|
|
|
}
|
2025-10-01 17:53:53 -04:00
|
|
|
|
2026-01-05 15:25:54 -05:00
|
|
|
export function logEditStrategy(
|
2025-10-01 17:53:53 -04:00
|
|
|
config: Config,
|
2026-01-05 15:25:54 -05:00
|
|
|
event: EditStrategyEvent,
|
2025-10-01 17:53:53 -04:00
|
|
|
): void {
|
2026-01-05 15:25:54 -05:00
|
|
|
ClearcutLogger.getInstance(config)?.logEditStrategyEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-10-01 17:53:53 -04:00
|
|
|
}
|
2025-10-01 18:35:45 -07:00
|
|
|
|
2026-01-05 15:25:54 -05:00
|
|
|
export function logEditCorrectionEvent(
|
2025-10-01 18:35:45 -07:00
|
|
|
config: Config,
|
2026-01-05 15:25:54 -05:00
|
|
|
event: EditCorrectionEvent,
|
2025-10-01 18:35:45 -07:00
|
|
|
): void {
|
2026-01-05 15:25:54 -05:00
|
|
|
ClearcutLogger.getInstance(config)?.logEditCorrectionEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-10-01 18:35:45 -07:00
|
|
|
}
|
2025-10-08 15:42:33 -04:00
|
|
|
|
|
|
|
|
export function logAgentStart(config: Config, event: AgentStartEvent): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logAgentStartEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-10-08 15:42:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function logAgentFinish(config: Config, event: AgentFinishEvent): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logAgentFinishEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
|
|
|
|
|
recordAgentRunMetrics(config, event);
|
|
|
|
|
});
|
2025-10-08 15:42:33 -04:00
|
|
|
}
|
2025-10-09 13:01:17 -04:00
|
|
|
|
2025-11-03 17:53:43 -05:00
|
|
|
export function logRecoveryAttempt(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: RecoveryAttemptEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logRecoveryAttemptEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
|
|
|
|
|
recordRecoveryAttemptMetrics(config, event);
|
|
|
|
|
});
|
2025-11-03 17:53:43 -05:00
|
|
|
}
|
|
|
|
|
|
2025-10-09 13:01:17 -04:00
|
|
|
export function logWebFetchFallbackAttempt(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: WebFetchFallbackAttemptEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logWebFetchFallbackAttemptEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-10-09 13:01:17 -04:00
|
|
|
}
|
2025-11-11 20:49:00 -08:00
|
|
|
|
|
|
|
|
export function logLlmLoopCheck(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: LlmLoopCheckEvent,
|
|
|
|
|
): void {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logLlmLoopCheckEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
2025-11-11 20:49:00 -08:00
|
|
|
}
|
2025-11-24 13:13:24 -08:00
|
|
|
|
2026-01-20 13:57:34 -05:00
|
|
|
export function logApprovalModeSwitch(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ApprovalModeSwitchEvent,
|
|
|
|
|
) {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logApprovalModeSwitchEvent(event);
|
|
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
logs.getLogger(SERVICE_NAME).emit({
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function logApprovalModeDuration(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: ApprovalModeDurationEvent,
|
|
|
|
|
) {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logApprovalModeDurationEvent(event);
|
|
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
logs.getLogger(SERVICE_NAME).emit({
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-05 18:46:34 -05:00
|
|
|
export function logPlanExecution(config: Config, event: PlanExecutionEvent) {
|
|
|
|
|
ClearcutLogger.getInstance(config)?.logPlanExecutionEvent(event);
|
|
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
logs.getLogger(SERVICE_NAME).emit({
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
recordPlanExecution(config, {
|
|
|
|
|
approval_mode: event.approval_mode,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-24 13:13:24 -08:00
|
|
|
export function logHookCall(config: Config, event: HookCallEvent): void {
|
2025-12-21 16:18:42 -05:00
|
|
|
ClearcutLogger.getInstance(config)?.logHookCallEvent(event);
|
2025-12-02 21:27:37 -08:00
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
|
|
|
|
|
recordHookCallMetrics(
|
|
|
|
|
config,
|
|
|
|
|
event.hook_event_name,
|
|
|
|
|
event.hook_name,
|
|
|
|
|
event.duration_ms,
|
|
|
|
|
event.success,
|
|
|
|
|
);
|
|
|
|
|
});
|
2025-11-24 13:13:24 -08:00
|
|
|
}
|
2025-12-08 12:29:50 -08:00
|
|
|
|
|
|
|
|
export function logStartupStats(
|
|
|
|
|
config: Config,
|
|
|
|
|
event: StartupStatsEvent,
|
|
|
|
|
): void {
|
|
|
|
|
bufferTelemetryEvent(() => {
|
|
|
|
|
const logger = logs.getLogger(SERVICE_NAME);
|
|
|
|
|
const logRecord: LogRecord = {
|
|
|
|
|
body: event.toLogBody(),
|
|
|
|
|
attributes: event.toOpenTelemetryAttributes(config),
|
|
|
|
|
};
|
|
|
|
|
logger.emit(logRecord);
|
|
|
|
|
});
|
|
|
|
|
}
|