deer social fork for personal usage. but you might see a use idk. github mirror
at main 4.1 kB view raw
1import {nanoid} from 'nanoid/non-secure' 2 3import {logEvent} from '#/lib/statsig/statsig' 4import {add} from '#/logger/logDump' 5import {type MetricEvents} from '#/logger/metrics' 6import {consoleTransport} from '#/logger/transports/console' 7import { 8 LogContext, 9 LogLevel, 10 type Metadata, 11 type Transport, 12} from '#/logger/types' 13import {enabledLogLevels} from '#/logger/util' 14import {ENV} from '#/env' 15 16const TRANSPORTS: Transport[] = (function configureTransports() { 17 switch (ENV) { 18 case 'production': { 19 return [] 20 } 21 case 'test': { 22 return [] 23 } 24 default: { 25 return [consoleTransport] 26 } 27 } 28})() 29 30export class Logger { 31 static Level = LogLevel 32 static Context = LogContext 33 34 level: LogLevel 35 context: LogContext | undefined = undefined 36 contextFilter: string = '' 37 38 protected debugContextRegexes: RegExp[] = [] 39 protected transports: Transport[] = [] 40 41 static create(context?: LogContext) { 42 const logger = new Logger({ 43 level: process.env.EXPO_PUBLIC_LOG_LEVEL as LogLevel, 44 context, 45 contextFilter: process.env.EXPO_PUBLIC_LOG_DEBUG || '', 46 }) 47 for (const transport of TRANSPORTS) { 48 logger.addTransport(transport) 49 } 50 return logger 51 } 52 53 constructor({ 54 level, 55 context, 56 contextFilter, 57 }: { 58 level?: LogLevel 59 context?: LogContext 60 contextFilter?: string 61 } = {}) { 62 this.context = context 63 this.level = level || LogLevel.Info 64 this.contextFilter = contextFilter || '' 65 if (this.contextFilter) { 66 this.level = LogLevel.Debug 67 } 68 this.debugContextRegexes = (this.contextFilter || '') 69 .split(',') 70 .map(filter => { 71 return new RegExp(filter.replace(/[^\w:*-]/, '').replace(/\*/g, '.*')) 72 }) 73 } 74 75 debug(message: string, metadata: Metadata = {}) { 76 this.transport({level: LogLevel.Debug, message, metadata}) 77 } 78 79 info(message: string, metadata: Metadata = {}) { 80 this.transport({level: LogLevel.Info, message, metadata}) 81 } 82 83 log(message: string, metadata: Metadata = {}) { 84 this.transport({level: LogLevel.Log, message, metadata}) 85 } 86 87 warn(message: string, metadata: Metadata = {}) { 88 this.transport({level: LogLevel.Warn, message, metadata}) 89 } 90 91 error(error: Error | string, metadata: Metadata = {}) { 92 this.transport({level: LogLevel.Error, message: error, metadata}) 93 } 94 95 metric<E extends keyof MetricEvents>( 96 event: E & string, 97 metadata: MetricEvents[E], 98 options: { 99 /** 100 * Optionally also send to StatSig 101 */ 102 statsig?: boolean 103 } = {statsig: true}, 104 ) { 105 logEvent(event, metadata, { 106 lake: !options.statsig, 107 }) 108 109 for (const transport of this.transports) { 110 transport(LogLevel.Info, LogContext.Metric, event, metadata, Date.now()) 111 } 112 } 113 114 addTransport(transport: Transport) { 115 this.transports.push(transport) 116 return () => { 117 this.transports.splice(this.transports.indexOf(transport), 1) 118 } 119 } 120 121 protected transport({ 122 level, 123 message, 124 metadata = {}, 125 }: { 126 level: LogLevel 127 message: string | Error 128 metadata: Metadata 129 }) { 130 if ( 131 level === LogLevel.Debug && 132 !!this.contextFilter && 133 !!this.context && 134 !this.debugContextRegexes.find(reg => reg.test(this.context!)) 135 ) 136 return 137 138 const timestamp = Date.now() 139 const meta = metadata || {} 140 141 // send every log to syslog 142 add({ 143 id: nanoid(), 144 timestamp, 145 level, 146 context: this.context, 147 message, 148 metadata: meta, 149 }) 150 151 if (!enabledLogLevels[this.level].includes(level)) return 152 153 for (const transport of this.transports) { 154 transport(level, this.context, message, meta, timestamp) 155 } 156 } 157} 158 159/** 160 * Default logger instance. See `@/logger/README` for docs. 161 * 162 * Basic usage: 163 * 164 * `logger.debug(message[, metadata])` 165 * `logger.info(message[, metadata])` 166 * `logger.log(message[, metadata])` 167 * `logger.warn(message[, metadata])` 168 * `logger.error(error[, metadata])` 169 */ 170export const logger = Logger.create(Logger.Context.Default)