From b87c3e8907b609f7de397c4e754e4efd995522e0 Mon Sep 17 00:00:00 2001 From: Hubert Sosinski Date: Sun, 30 Nov 2025 13:02:42 +0100 Subject: [PATCH 1/5] Introduce forwardLogsToSentry.ts --- src/libs/Log.ts | 3 ++ src/libs/telemetry/forwardLogsToSentry.ts | 66 +++++++++++++++++++++++ src/setup/telemetry/index.ts | 1 + 3 files changed, 70 insertions(+) create mode 100644 src/libs/telemetry/forwardLogsToSentry.ts diff --git a/src/libs/Log.ts b/src/libs/Log.ts index 62e305fd6c7bb..fb77ebb4ae133 100644 --- a/src/libs/Log.ts +++ b/src/libs/Log.ts @@ -9,6 +9,7 @@ import Onyx from 'react-native-onyx'; import type {Merge} from 'type-fest'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import forwardLogsToSentry from './telemetry/forwardLogsToSentry'; import pkg from '../../package.json'; import {addLog, flushAllLogsOnAppLaunch} from './actions/Console'; import {shouldAttachLog} from './Console'; @@ -59,6 +60,8 @@ function serverLoggingCallback(logger: Logger, params: ServerLoggingCallbackOpti if (requestParams.parameters) { requestParams.parameters = JSON.stringify(requestParams.parameters); } + // Mirror backend log payload into Telemetry logger for better context + forwardLogsToSentry(requestParams.logPacket); clearTimeout(timeout); timeout = setTimeout(() => logger.info('Flushing logs older than 10 minutes', true, {}, true), 10 * 60 * 1000); return LogCommand(requestParams); diff --git a/src/libs/telemetry/forwardLogsToSentry.ts b/src/libs/telemetry/forwardLogsToSentry.ts new file mode 100644 index 0000000000000..014dea64e6d58 --- /dev/null +++ b/src/libs/telemetry/forwardLogsToSentry.ts @@ -0,0 +1,66 @@ +import * as Sentry from '@sentry/react-native'; + + +type SentryLogLevel = 'debug' | 'info' | 'warn' | 'error'; + +/** + * Method deciding whether a log packet should be forwarded to Sentry. + * Currently, this always returns false because we want to deliberately decide what is being forwarded. + */ +function shouldForwardLog(log: {message?: string; parameters?: Record | undefined}) { // eslint-disable-line @typescript-eslint/no-unused-vars + return false; +} + +function mapLogMessageToSentryLevel(message: string): SentryLogLevel { + if (message.startsWith('[alrt]')) { + return 'error'; + } + if (message.startsWith('[warn]') || message.startsWith('[hmmm]')) { + return 'warn'; + } + if (message.startsWith('[info]')) { + return 'info'; + } + return 'debug'; +} + +function forwardLogsToSentry(logPacket: string | undefined) { + if (!logPacket) { + return; + } + + let parsedPacket: Array<{message?: string; parameters?: Record | undefined}> | undefined; + try { + parsedPacket = JSON.parse(logPacket) as typeof parsedPacket; + } catch { + Sentry.logger.warn('Failed to parse log packet for Sentry forwarding', {logPacket}); + return; + } + + if (!Array.isArray(parsedPacket)) { + return; + } + + for (const logLine of parsedPacket) { + if (!logLine || typeof logLine.message !== 'string') { + continue; + } + if (!shouldForwardLog(logLine)) { + return; + } + + const level = mapLogMessageToSentryLevel(logLine.message); + const logMethod = Sentry.logger[level]; + if (!logMethod) { + continue; + } + + if (logLine.parameters) { + logMethod(logLine.message, logLine.parameters); + } else { + logMethod(logLine.message); + } + } +} + +export default forwardLogsToSentry; \ No newline at end of file diff --git a/src/setup/telemetry/index.ts b/src/setup/telemetry/index.ts index 726b4ca806dc4..77013c9c2bf3e 100644 --- a/src/setup/telemetry/index.ts +++ b/src/setup/telemetry/index.ts @@ -23,6 +23,7 @@ export default function (): void { environment: CONFIG.ENVIRONMENT, release: `${pkg.name}@${pkg.version}`, beforeSendTransaction: processBeforeSendTransactions, + enableLogs: true, }); startSpan(CONST.TELEMETRY.SPAN_APP_STARTUP, { From faf4ad220f73447e9f7d51c351b84f7030c68df4 Mon Sep 17 00:00:00 2001 From: Hubert Sosinski Date: Sun, 30 Nov 2025 21:43:06 +0100 Subject: [PATCH 2/5] Organize imports and add "alrt" to cspell dictionary --- cspell.json | 1 + src/libs/Log.ts | 2 +- src/libs/telemetry/forwardLogsToSentry.ts | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cspell.json b/cspell.json index 82a172987070c..5bed00bb7302f 100644 --- a/cspell.json +++ b/cspell.json @@ -16,6 +16,7 @@ "Airplus", "airshipconfig", "airside", + "alrt", "Amal", "Amal's", "americanexpressfdx", diff --git a/src/libs/Log.ts b/src/libs/Log.ts index fb77ebb4ae133..57fc67a41f51d 100644 --- a/src/libs/Log.ts +++ b/src/libs/Log.ts @@ -9,13 +9,13 @@ import Onyx from 'react-native-onyx'; import type {Merge} from 'type-fest'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import forwardLogsToSentry from './telemetry/forwardLogsToSentry'; import pkg from '../../package.json'; import {addLog, flushAllLogsOnAppLaunch} from './actions/Console'; import {shouldAttachLog} from './Console'; import getPlatform from './getPlatform'; import {post} from './Network'; import requireParameters from './requireParameters'; +import forwardLogsToSentry from './telemetry/forwardLogsToSentry'; let timeout: NodeJS.Timeout; let shouldCollectLogs = false; diff --git a/src/libs/telemetry/forwardLogsToSentry.ts b/src/libs/telemetry/forwardLogsToSentry.ts index 014dea64e6d58..750d0e2308023 100644 --- a/src/libs/telemetry/forwardLogsToSentry.ts +++ b/src/libs/telemetry/forwardLogsToSentry.ts @@ -1,13 +1,13 @@ import * as Sentry from '@sentry/react-native'; - type SentryLogLevel = 'debug' | 'info' | 'warn' | 'error'; /** * Method deciding whether a log packet should be forwarded to Sentry. * Currently, this always returns false because we want to deliberately decide what is being forwarded. */ -function shouldForwardLog(log: {message?: string; parameters?: Record | undefined}) { // eslint-disable-line @typescript-eslint/no-unused-vars +function shouldForwardLog(log: {message?: string; parameters?: Record | undefined}) { + // eslint-disable-line @typescript-eslint/no-unused-vars return false; } @@ -63,4 +63,4 @@ function forwardLogsToSentry(logPacket: string | undefined) { } } -export default forwardLogsToSentry; \ No newline at end of file +export default forwardLogsToSentry; From b7d98944827f390f54dd598b74ec56bd9264ead4 Mon Sep 17 00:00:00 2001 From: Hubert Sosinski Date: Sun, 30 Nov 2025 21:49:56 +0100 Subject: [PATCH 3/5] Fix loop bad ending --- src/libs/telemetry/forwardLogsToSentry.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/telemetry/forwardLogsToSentry.ts b/src/libs/telemetry/forwardLogsToSentry.ts index 750d0e2308023..5b129986bca0b 100644 --- a/src/libs/telemetry/forwardLogsToSentry.ts +++ b/src/libs/telemetry/forwardLogsToSentry.ts @@ -6,8 +6,8 @@ type SentryLogLevel = 'debug' | 'info' | 'warn' | 'error'; * Method deciding whether a log packet should be forwarded to Sentry. * Currently, this always returns false because we want to deliberately decide what is being forwarded. */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars function shouldForwardLog(log: {message?: string; parameters?: Record | undefined}) { - // eslint-disable-line @typescript-eslint/no-unused-vars return false; } @@ -46,7 +46,7 @@ function forwardLogsToSentry(logPacket: string | undefined) { continue; } if (!shouldForwardLog(logLine)) { - return; + continue; } const level = mapLogMessageToSentryLevel(logLine.message); From e28ceed86ca82e6e012a03e07a5dfa12bb250405 Mon Sep 17 00:00:00 2001 From: Hubert Sosinski Date: Tue, 9 Dec 2025 12:06:00 +0100 Subject: [PATCH 4/5] Add comment --- src/libs/telemetry/forwardLogsToSentry.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/telemetry/forwardLogsToSentry.ts b/src/libs/telemetry/forwardLogsToSentry.ts index 5b129986bca0b..a989ae8c9fbe2 100644 --- a/src/libs/telemetry/forwardLogsToSentry.ts +++ b/src/libs/telemetry/forwardLogsToSentry.ts @@ -4,7 +4,10 @@ type SentryLogLevel = 'debug' | 'info' | 'warn' | 'error'; /** * Method deciding whether a log packet should be forwarded to Sentry. + * + * ATTENTION! * Currently, this always returns false because we want to deliberately decide what is being forwarded. + * There is no redaction / filtering of sensitive data implemented yet. When you'll implement any log forwarding logic, make sure that you do not leak any sensitive data. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars function shouldForwardLog(log: {message?: string; parameters?: Record | undefined}) { From ec7789a96e4b7c14f06d64df813fb77137a4b3e1 Mon Sep 17 00:00:00 2001 From: Hubert Sosinski Date: Tue, 9 Dec 2025 12:06:12 +0100 Subject: [PATCH 5/5] Add comment --- src/libs/telemetry/forwardLogsToSentry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/telemetry/forwardLogsToSentry.ts b/src/libs/telemetry/forwardLogsToSentry.ts index a989ae8c9fbe2..7983063ce4c90 100644 --- a/src/libs/telemetry/forwardLogsToSentry.ts +++ b/src/libs/telemetry/forwardLogsToSentry.ts @@ -7,7 +7,7 @@ type SentryLogLevel = 'debug' | 'info' | 'warn' | 'error'; * * ATTENTION! * Currently, this always returns false because we want to deliberately decide what is being forwarded. - * There is no redaction / filtering of sensitive data implemented yet. When you'll implement any log forwarding logic, make sure that you do not leak any sensitive data. + * There is no redaction / filtering of sensitive data implemented yet. When you implement any log forwarding logic, make sure that you do not leak any sensitive data. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars function shouldForwardLog(log: {message?: string; parameters?: Record | undefined}) {