From e388de1f6a29953b096d854b1e9f67745bb42b72 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 29 Apr 2025 13:09:32 -0400 Subject: [PATCH 1/2] feat(cloudflare): Add logs exports --- packages/cloudflare/src/index.ts | 2 + packages/cloudflare/src/logs/exports.ts | 205 ++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 packages/cloudflare/src/logs/exports.ts diff --git a/packages/cloudflare/src/index.ts b/packages/cloudflare/src/index.ts index 5a62c51e7e41..e34d201a1160 100644 --- a/packages/cloudflare/src/index.ts +++ b/packages/cloudflare/src/index.ts @@ -91,6 +91,8 @@ export { wrapMcpServerWithSentry, } from '@sentry/core'; +export * as logger from './logs/exports'; + export { withSentry } from './handler'; export { sentryPagesPlugin } from './pages-plugin'; diff --git a/packages/cloudflare/src/logs/exports.ts b/packages/cloudflare/src/logs/exports.ts new file mode 100644 index 000000000000..ef2614b81f55 --- /dev/null +++ b/packages/cloudflare/src/logs/exports.ts @@ -0,0 +1,205 @@ +import type { Log, LogSeverityLevel, ParameterizedString } from '@sentry/core'; +import { _INTERNAL_captureLog } from '@sentry/core'; + +/** + * Capture a log with the given level. + * + * @param level - The level of the log. + * @param message - The message to log. + * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100. + * @param severityNumber - The severity number of the log. + */ +function captureLog( + level: LogSeverityLevel, + message: ParameterizedString, + attributes?: Log['attributes'], + severityNumber?: Log['severityNumber'], +): void { + _INTERNAL_captureLog({ level, message, attributes, severityNumber }); +} + +/** + * @summary Capture a log with the `trace` level. Requires `_experiments.enableLogs` to be enabled. + * + * @param message - The message to log. + * @param attributes - Arbitrary structured data that stores information about the log - e.g., { userId: 100, route: '/dashboard' }. + * + * @example + * + * ``` + * Sentry.logger.trace('User clicked submit button', { + * buttonId: 'submit-form', + * formId: 'user-profile', + * timestamp: Date.now() + * }); + * ``` + * + * @example With template strings + * + * ``` + * Sentry.logger.trace(Sentry.logger.fmt`User ${user} navigated to ${page}`, { + * userId: '123', + * sessionId: 'abc-xyz' + * }); + * ``` + */ +export function trace(message: ParameterizedString, attributes?: Log['attributes']): void { + captureLog('trace', message, attributes); +} + +/** + * @summary Capture a log with the `debug` level. Requires `_experiments.enableLogs` to be enabled. + * + * @param message - The message to log. + * @param attributes - Arbitrary structured data that stores information about the log - e.g., { component: 'Header', state: 'loading' }. + * + * @example + * + * ``` + * Sentry.logger.debug('Component mounted', { + * component: 'UserProfile', + * props: { userId: 123 }, + * renderTime: 150 + * }); + * ``` + * + * @example With template strings + * + * ``` + * Sentry.logger.debug(Sentry.logger.fmt`API request to ${endpoint} failed`, { + * statusCode: 404, + * requestId: 'req-123', + * duration: 250 + * }); + * ``` + */ +export function debug(message: ParameterizedString, attributes?: Log['attributes']): void { + captureLog('debug', message, attributes); +} + +/** + * @summary Capture a log with the `info` level. Requires `_experiments.enableLogs` to be enabled. + * + * @param message - The message to log. + * @param attributes - Arbitrary structured data that stores information about the log - e.g., { feature: 'checkout', status: 'completed' }. + * + * @example + * + * ``` + * Sentry.logger.info('User completed checkout', { + * orderId: 'order-123', + * amount: 99.99, + * paymentMethod: 'credit_card' + * }); + * ``` + * + * @example With template strings + * + * ``` + * Sentry.logger.info(Sentry.logger.fmt`User ${user} updated profile picture`, { + * userId: 'user-123', + * imageSize: '2.5MB', + * timestamp: Date.now() + * }); + * ``` + */ +export function info(message: ParameterizedString, attributes?: Log['attributes']): void { + captureLog('info', message, attributes); +} + +/** + * @summary Capture a log with the `warn` level. Requires `_experiments.enableLogs` to be enabled. + * + * @param message - The message to log. + * @param attributes - Arbitrary structured data that stores information about the log - e.g., { browser: 'Chrome', version: '91.0' }. + * + * @example + * + * ``` + * Sentry.logger.warn('Browser compatibility issue detected', { + * browser: 'Safari', + * version: '14.0', + * feature: 'WebRTC', + * fallback: 'enabled' + * }); + * ``` + * + * @example With template strings + * + * ``` + * Sentry.logger.warn(Sentry.logger.fmt`API endpoint ${endpoint} is deprecated`, { + * recommendedEndpoint: '/api/v2/users', + * sunsetDate: '2024-12-31', + * clientVersion: '1.2.3' + * }); + * ``` + */ +export function warn(message: ParameterizedString, attributes?: Log['attributes']): void { + captureLog('warn', message, attributes); +} + +/** + * @summary Capture a log with the `error` level. Requires `_experiments.enableLogs` to be enabled. + * + * @param message - The message to log. + * @param attributes - Arbitrary structured data that stores information about the log - e.g., { error: 'NetworkError', url: '/api/data' }. + * + * @example + * + * ``` + * Sentry.logger.error('Failed to load user data', { + * error: 'NetworkError', + * url: '/api/users/123', + * statusCode: 500, + * retryCount: 3 + * }); + * ``` + * + * @example With template strings + * + * ``` + * Sentry.logger.error(Sentry.logger.fmt`Payment processing failed for order ${orderId}`, { + * error: 'InsufficientFunds', + * amount: 100.00, + * currency: 'USD', + * userId: 'user-456' + * }); + * ``` + */ +export function error(message: ParameterizedString, attributes?: Log['attributes']): void { + captureLog('error', message, attributes); +} + +/** + * @summary Capture a log with the `fatal` level. Requires `_experiments.enableLogs` to be enabled. + * + * @param message - The message to log. + * @param attributes - Arbitrary structured data that stores information about the log - e.g., { appState: 'corrupted', sessionId: 'abc-123' }. + * + * @example + * + * ``` + * Sentry.logger.fatal('Application state corrupted', { + * lastKnownState: 'authenticated', + * sessionId: 'session-123', + * timestamp: Date.now(), + * recoveryAttempted: true + * }); + * ``` + * + * @example With template strings + * + * ``` + * Sentry.logger.fatal(Sentry.logger.fmt`Critical system failure in ${service}`, { + * service: 'payment-processor', + * errorCode: 'CRITICAL_FAILURE', + * affectedUsers: 150, + * timestamp: Date.now() + * }); + * ``` + */ +export function fatal(message: ParameterizedString, attributes?: Log['attributes']): void { + captureLog('fatal', message, attributes); +} + +export { fmt } from '@sentry/core'; From becad6e07b30a384c021be10c0a2c23d3ea067c6 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 2 May 2025 12:05:34 -0400 Subject: [PATCH 2/2] console logging integration --- packages/cloudflare/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cloudflare/src/index.ts b/packages/cloudflare/src/index.ts index 530847ccbb84..64a6f57fccc2 100644 --- a/packages/cloudflare/src/index.ts +++ b/packages/cloudflare/src/index.ts @@ -89,6 +89,7 @@ export { spanToBaggageHeader, updateSpanName, wrapMcpServerWithSentry, + consoleLoggingIntegration, } from '@sentry/core'; export * as logger from './logs/exports';