d4b23d3ab4
* Clean up env files * Use new env in Sentry setup file * Use new env in Bitdrift setup file * Use new env in chat proxy header * Prefix Bitdrift key with EXPO_PUBLIC * Deprecate SENTRY_RELEASE since we use package.json now * Use existing EXPO_PUBLIC_BUNDLE_IDENTIFIER short commit has as Sentry dist value * Fix missing bundle identifier for Render deploys * Deprecate SENTRY_DIST in favor of EXPO_PUBLIC_BUNDLE_IDENTIFIER * Prefix SENTRY_DSN with EXPO_PUBLIC to match others * Remove debugging field * Replace NODE_ENV in places where its safe * Self review * Properly patch Sentry package * Echo variables to .env in Dockerfile instead of passing to shell script * Make sure EXPO_PUBLIC_ENV is set for web container builds * Update IS_TESTFLIGHT to include testflight-android * Slice bundle hash to match other platforms, needed for render.com deployments * [APP-1331] Migrate `app-info` to new env (#8703) * Move env files into directory with platform specific files * Migrate usages of app-info to new env * Fix bad import * Update BUNDLE_DATE format comment * Trim RENDER_GIT_COMMIT to first 7 to match --short sha * Clarify build process env vars and ensure they are explicitly passed in * Revert Sentry patch as a result of prev commit * Update webpack Sentry dist value based on prev commits * Add PACKAGE_VERSION and replace in statsig to fix conflict * Fix render substitution syntax * Remove invalid syntax * Remove unnecessary testflight check * Just use long commit hash * Slice full hash for display in app * Fix missing space in ios workflow * Pass in sentry CLI env vars, align matching values * Align on RELEASE_VERSION * Add new env setup to missed OTA spot * Update webpack to use same SENTRY_RELEASE var * Just fallback to package version for Render deploys * Remove TF check for BUNDLE_DATE * Set EXPO_PUBLIC_ENV for bundle update * Consistent naming "Env" * Add comment * Use RELEASE_VERSION instead of package.json * Update PR comment CI
176 lines
4.2 KiB
TypeScript
176 lines
4.2 KiB
TypeScript
import {nanoid} from 'nanoid/non-secure'
|
|
|
|
import {logEvent} from '#/lib/statsig/statsig'
|
|
import {add} from '#/logger/logDump'
|
|
import {type MetricEvents} from '#/logger/metrics'
|
|
import {bitdriftTransport} from '#/logger/transports/bitdrift'
|
|
import {consoleTransport} from '#/logger/transports/console'
|
|
import {sentryTransport} from '#/logger/transports/sentry'
|
|
import {
|
|
LogContext,
|
|
LogLevel,
|
|
type Metadata,
|
|
type Transport,
|
|
} from '#/logger/types'
|
|
import {enabledLogLevels} from '#/logger/util'
|
|
import {isNative} from '#/platform/detection'
|
|
import {ENV} from '#/env'
|
|
|
|
const TRANSPORTS: Transport[] = (function configureTransports() {
|
|
switch (ENV) {
|
|
case 'production': {
|
|
return [sentryTransport, isNative && bitdriftTransport].filter(
|
|
Boolean,
|
|
) as Transport[]
|
|
}
|
|
case 'test': {
|
|
return []
|
|
}
|
|
default: {
|
|
return [consoleTransport]
|
|
}
|
|
}
|
|
})()
|
|
|
|
export class Logger {
|
|
static Level = LogLevel
|
|
static Context = LogContext
|
|
|
|
level: LogLevel
|
|
context: LogContext | undefined = undefined
|
|
contextFilter: string = ''
|
|
|
|
protected debugContextRegexes: RegExp[] = []
|
|
protected transports: Transport[] = []
|
|
|
|
static create(context?: LogContext) {
|
|
const logger = new Logger({
|
|
level: process.env.EXPO_PUBLIC_LOG_LEVEL as LogLevel,
|
|
context,
|
|
contextFilter: process.env.EXPO_PUBLIC_LOG_DEBUG || '',
|
|
})
|
|
for (const transport of TRANSPORTS) {
|
|
logger.addTransport(transport)
|
|
}
|
|
return logger
|
|
}
|
|
|
|
constructor({
|
|
level,
|
|
context,
|
|
contextFilter,
|
|
}: {
|
|
level?: LogLevel
|
|
context?: LogContext
|
|
contextFilter?: string
|
|
} = {}) {
|
|
this.context = context
|
|
this.level = level || LogLevel.Info
|
|
this.contextFilter = contextFilter || ''
|
|
if (this.contextFilter) {
|
|
this.level = LogLevel.Debug
|
|
}
|
|
this.debugContextRegexes = (this.contextFilter || '')
|
|
.split(',')
|
|
.map(filter => {
|
|
return new RegExp(filter.replace(/[^\w:*-]/, '').replace(/\*/g, '.*'))
|
|
})
|
|
}
|
|
|
|
debug(message: string, metadata: Metadata = {}) {
|
|
this.transport({level: LogLevel.Debug, message, metadata})
|
|
}
|
|
|
|
info(message: string, metadata: Metadata = {}) {
|
|
this.transport({level: LogLevel.Info, message, metadata})
|
|
}
|
|
|
|
log(message: string, metadata: Metadata = {}) {
|
|
this.transport({level: LogLevel.Log, message, metadata})
|
|
}
|
|
|
|
warn(message: string, metadata: Metadata = {}) {
|
|
this.transport({level: LogLevel.Warn, message, metadata})
|
|
}
|
|
|
|
error(error: Error | string, metadata: Metadata = {}) {
|
|
this.transport({level: LogLevel.Error, message: error, metadata})
|
|
}
|
|
|
|
metric<E extends keyof MetricEvents>(
|
|
event: E & string,
|
|
metadata: MetricEvents[E],
|
|
options: {
|
|
/**
|
|
* Optionally also send to StatSig
|
|
*/
|
|
statsig?: boolean
|
|
} = {statsig: true},
|
|
) {
|
|
logEvent(event, metadata, {
|
|
lake: !options.statsig,
|
|
})
|
|
|
|
for (const transport of this.transports) {
|
|
transport(LogLevel.Info, LogContext.Metric, event, metadata, Date.now())
|
|
}
|
|
}
|
|
|
|
addTransport(transport: Transport) {
|
|
this.transports.push(transport)
|
|
return () => {
|
|
this.transports.splice(this.transports.indexOf(transport), 1)
|
|
}
|
|
}
|
|
|
|
protected transport({
|
|
level,
|
|
message,
|
|
metadata = {},
|
|
}: {
|
|
level: LogLevel
|
|
message: string | Error
|
|
metadata: Metadata
|
|
}) {
|
|
if (
|
|
level === LogLevel.Debug &&
|
|
!!this.contextFilter &&
|
|
!!this.context &&
|
|
!this.debugContextRegexes.find(reg => reg.test(this.context!))
|
|
)
|
|
return
|
|
|
|
const timestamp = Date.now()
|
|
const meta = metadata || {}
|
|
|
|
// send every log to syslog
|
|
add({
|
|
id: nanoid(),
|
|
timestamp,
|
|
level,
|
|
context: this.context,
|
|
message,
|
|
metadata: meta,
|
|
})
|
|
|
|
if (!enabledLogLevels[this.level].includes(level)) return
|
|
|
|
for (const transport of this.transports) {
|
|
transport(level, this.context, message, meta, timestamp)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Default logger instance. See `@/logger/README` for docs.
|
|
*
|
|
* Basic usage:
|
|
*
|
|
* `logger.debug(message[, metadata])`
|
|
* `logger.info(message[, metadata])`
|
|
* `logger.log(message[, metadata])`
|
|
* `logger.warn(message[, metadata])`
|
|
* `logger.error(error[, metadata])`
|
|
*/
|
|
export const logger = Logger.create(Logger.Context.Default)
|