diff --git a/src/lib/bitdrift.ts b/src/lib/bitdrift.ts index 02d074e76c..3f892f6b8c 100644 --- a/src/lib/bitdrift.ts +++ b/src/lib/bitdrift.ts @@ -1,5 +1,6 @@ import {init} from '@bitdrift/react-native' import {Statsig} from 'statsig-react-native-expo' +export {debug, error, info, warn} from '@bitdrift/react-native' import {initPromise} from './statsig/statsig' diff --git a/src/lib/bitdrift.web.ts b/src/lib/bitdrift.web.ts new file mode 100644 index 0000000000..5db69450fa --- /dev/null +++ b/src/lib/bitdrift.web.ts @@ -0,0 +1,4 @@ +export function debug() {} +export function error() {} +export function info() {} +export function warn() {} diff --git a/src/lib/statsig/statsig.tsx b/src/lib/statsig/statsig.tsx index d2db6bc330..ec29f0a717 100644 --- a/src/lib/statsig/statsig.tsx +++ b/src/lib/statsig/statsig.tsx @@ -5,6 +5,7 @@ import {sha256} from 'js-sha256' import {Statsig, StatsigProvider} from 'statsig-react-native-expo' import {BUNDLE_DATE, BUNDLE_IDENTIFIER, IS_TESTFLIGHT} from '#/lib/app-info' +import * as bitdrift from '#/lib/bitdrift' import {logger} from '#/logger' import {isWeb} from '#/platform/detection' import * as persisted from '#/state/persisted' @@ -97,21 +98,47 @@ export function logEvent( rawMetadata: LogEvents[E] & FlatJSONRecord, ) { try { - const fullMetadata = { - ...rawMetadata, - } as Record // Statsig typings are unnecessarily strict here. + const fullMetadata = toStringRecord(rawMetadata) fullMetadata.routeName = getCurrentRouteName() ?? '(Uninitialized)' if (Statsig.initializeCalled()) { Statsig.logEvent(eventName, null, fullMetadata) } - logger.info(eventName) - logger.debug(JSON.stringify(fullMetadata)) + // Intentionally call console and bitdrift directly so we can pass rich objects. + if (isWeb) { + console.groupCollapsed(eventName) + console.log(fullMetadata) + console.groupEnd() + } else { + bitdrift.info(eventName, fullMetadata) + console.log( + eventName, + '\x1b[2m', // dim + fullMetadata, + '\x1b[0m', // undim + ) + } } catch (e) { // A log should never interrupt the calling code, whatever happens. logger.error('Failed to log an event', {message: e}) } } +function toStringRecord( + metadata: LogEvents[E] & FlatJSONRecord, +): Record { + const record: Record = {} + for (let key in metadata) { + if (metadata.hasOwnProperty(key)) { + if (typeof metadata[key] === 'string') { + record[key] = metadata[key] + } else { + record[key] = JSON.stringify(metadata[key]) + } + } + } + return record +} + // We roll our own cache in front of Statsig because it is a singleton // and it's been difficult to get it to behave in a predictable way. // Our own cache ensures consistent evaluation within a single session. diff --git a/src/logger/bitdriftTransport.ts b/src/logger/bitdriftTransport.ts index c2235e0d4b..159b863004 100644 --- a/src/logger/bitdriftTransport.ts +++ b/src/logger/bitdriftTransport.ts @@ -3,8 +3,7 @@ import { error as bdError, info as bdInfo, warn as bdWarn, -} from '@bitdrift/react-native' - +} from '../lib/bitdrift' import {LogLevel, Transport} from './types' export function createBitdriftTransport(): Transport { @@ -18,6 +17,6 @@ export function createBitdriftTransport(): Transport { return (level, message) => { const log = logFunctions[level] - log(message.toString()) + log('' + message) } } diff --git a/src/logger/bitdriftTransport.web.ts b/src/logger/bitdriftTransport.web.ts deleted file mode 100644 index ecea3f6f3b..0000000000 --- a/src/logger/bitdriftTransport.web.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {Transport} from './index' - -export function createBitdriftTransport(): Transport { - return (_level, _message) => { - // noop - } -}