diff --git a/packages/chronos/chronos.ts b/packages/chronos/chronos.ts index 2ac79da82fa..e193a25676e 100644 --- a/packages/chronos/chronos.ts +++ b/packages/chronos/chronos.ts @@ -17,6 +17,7 @@ import {CronJob} from 'cron' import getGraphQLExecutor from 'parabol-server/utils/getGraphQLExecutor' +import {Logger} from 'parabol-server/utils/Logger' import publishWebhookGQL from 'parabol-server/utils/publishWebhookGQL' interface PossibleJob { @@ -124,13 +125,13 @@ const chronos = () => { cronTime: cronTime!, onTick }) - console.log(`🌱 Chronos Job ${name}: STARTED`) + Logger.log(`🌱 Chronos Job ${name}: STARTED`) } catch { - console.log(`🌱 Chronos Job ${name}: SKIPPED`) + Logger.log(`🌱 Chronos Job ${name}: SKIPPED`) } }) - console.log(`\n🌾🌾🌾 Server ID: ${SERVER_ID}. Ready for Chronos 🌾🌾🌾`) + Logger.log(`\n🌾🌾🌾 Server ID: ${SERVER_ID}. Ready for Chronos 🌾🌾🌾`) } chronos() diff --git a/packages/embedder/ai_models/OpenAIGeneration.ts b/packages/embedder/ai_models/OpenAIGeneration.ts index 2bd97a32822..a67b328ff69 100644 --- a/packages/embedder/ai_models/OpenAIGeneration.ts +++ b/packages/embedder/ai_models/OpenAIGeneration.ts @@ -1,4 +1,5 @@ import OpenAI from 'openai' +import {Logger} from '../../server/utils/Logger' import { AbstractGenerationModel, GenerationModelParams, @@ -37,7 +38,7 @@ export class OpenAIGeneration extends AbstractGenerationModel { async summarize(content: string, options: OpenAIGenerationOptions) { if (!this.openAIApi) { const eMsg = 'OpenAI is not configured' - console.log('OpenAIGenerationSummarizer.summarize(): ', eMsg) + Logger.log('OpenAIGenerationSummarizer.summarize(): ', eMsg) throw new Error(eMsg) } const {maxNewTokens: max_tokens = 512, seed, stop, temperature = 0.8, topP: top_p} = options @@ -64,7 +65,7 @@ export class OpenAIGeneration extends AbstractGenerationModel { if (!maybeSummary) throw new Error('OpenAI returned empty summary') return maybeSummary } catch (e) { - console.log('OpenAIGenerationSummarizer.summarize(): ', e) + Logger.log('OpenAIGenerationSummarizer.summarize(): ', e) throw e } } diff --git a/packages/embedder/ai_models/TextGenerationInference.ts b/packages/embedder/ai_models/TextGenerationInference.ts index 96d7fdde89f..db0871083c1 100644 --- a/packages/embedder/ai_models/TextGenerationInference.ts +++ b/packages/embedder/ai_models/TextGenerationInference.ts @@ -1,3 +1,4 @@ +import {Logger} from '../../server/utils/Logger' import { AbstractGenerationModel, GenerationModelParams, @@ -52,7 +53,7 @@ export class TextGenerationInference extends AbstractGenerationModel { throw new Error('TextGenerationInference.summarize(): malformed response') return json.generated_text as string } catch (e) { - console.log('TextGenerationInferenceSummarizer.summarize(): timeout') + Logger.log('TextGenerationInferenceSummarizer.summarize(): timeout') throw e } } diff --git a/packages/embedder/ai_models/helpers/fetchWithRetry.ts b/packages/embedder/ai_models/helpers/fetchWithRetry.ts index 15668f95e4c..1d296b7b93e 100644 --- a/packages/embedder/ai_models/helpers/fetchWithRetry.ts +++ b/packages/embedder/ai_models/helpers/fetchWithRetry.ts @@ -1,3 +1,5 @@ +import {Logger} from '../../../server/utils/Logger' + interface FetchWithRetryOptions extends RequestInit { deadline: Date // Deadline for the request to complete debug?: boolean // Enable debug tracing @@ -22,7 +24,7 @@ export default async (url: RequestInfo, options: FetchWithRetryOptions): Promise attempt++ if (debug) { - console.log(`Attempt ${attempt}: Fetching ${JSON.stringify(url)}`) + Logger.log(`Attempt ${attempt}: Fetching ${JSON.stringify(url)}`) } const response = await fetch(url, fetchOptions) @@ -40,7 +42,7 @@ export default async (url: RequestInfo, options: FetchWithRetryOptions): Promise waitTime = Math.min(waitTime, deadline.getTime() - Date.now()) if (debug) { - console.log( + Logger.log( `Waiting ${waitTime / 1000} seconds before retrying due to status ${response.status}...` ) } @@ -54,7 +56,7 @@ export default async (url: RequestInfo, options: FetchWithRetryOptions): Promise throw new Error('Request aborted due to deadline') } if (debug) { - console.error(`Attempt ${attempt} failed: ${error}`) + Logger.error(`Attempt ${attempt} failed: ${error}`) } const currentTime = Date.now() if (currentTime >= deadline.getTime()) { diff --git a/packages/embedder/debug.ts b/packages/embedder/debug.ts index 7edd0a011f6..48390d03614 100644 --- a/packages/embedder/debug.ts +++ b/packages/embedder/debug.ts @@ -1,6 +1,7 @@ // call with yarn sucrase-node billing/debug.ts import '../../scripts/webpack/utils/dotenv' import getKysely from '../server/postgres/getKysely' +import {Logger} from '../server/utils/Logger' import {WorkflowOrchestrator} from './WorkflowOrchestrator' const debugFailedJob = async () => { @@ -14,11 +15,11 @@ const debugFailedJob = async () => { .executeTakeFirst() if (!failedJob) { - console.log('No failed jobs found') + Logger.log('No failed jobs found') return } - console.log('Debugging job:', failedJob.id) + Logger.log('Debugging job:', failedJob.id) const orch = new WorkflowOrchestrator() await orch.runStep(failedJob as any) // const man = getModelManager() diff --git a/packages/embedder/logMemoryUse.ts b/packages/embedder/logMemoryUse.ts index 46ae3b03968..cd02d30511a 100644 --- a/packages/embedder/logMemoryUse.ts +++ b/packages/embedder/logMemoryUse.ts @@ -1,3 +1,5 @@ +import {Logger} from '../server/utils/Logger' + // Not for use in prod, but useful for dev export const logMemoryUse = () => { const MB = 2 ** 20 @@ -5,6 +7,6 @@ export const logMemoryUse = () => { const memoryUsage = process.memoryUsage() const {rss} = memoryUsage const usedMB = Math.floor(rss / MB) - console.log('Memory use:', usedMB, 'MB') + Logger.log('Memory use:', usedMB, 'MB') }, 10000).unref() } diff --git a/packages/gql-executor/gqlExecutor.ts b/packages/gql-executor/gqlExecutor.ts index 7d97a8145b2..b1af4126fd2 100644 --- a/packages/gql-executor/gqlExecutor.ts +++ b/packages/gql-executor/gqlExecutor.ts @@ -8,6 +8,7 @@ import '../server/monkeyPatchFetch' import {GQLRequest} from '../server/types/custom' import RedisInstance from '../server/utils/RedisInstance' import RedisStream from './RedisStream' +import {Logger} from '../server/utils/Logger' tracer.init({ service: `gql`, @@ -31,14 +32,14 @@ const run = async () => { // on shutdown, remove consumer from the group process.on('SIGTERM', async (signal) => { - console.log(`Server ID: ${SERVER_ID}. Kill signal received: ${signal}, starting graceful shutdown.`) + Logger.log(`Server ID: ${SERVER_ID}. Kill signal received: ${signal}, starting graceful shutdown.`) await publisher.xgroup( 'DELCONSUMER', ServerChannel.GQL_EXECUTOR_STREAM, ServerChannel.GQL_EXECUTOR_CONSUMER_GROUP, executorChannel ) - console.log(`Server ID: ${SERVER_ID}. Graceful shutdown complete, exiting.`) + Logger.log(`Server ID: ${SERVER_ID}. Graceful shutdown complete, exiting.`) process.exit() }) @@ -71,7 +72,7 @@ const run = async () => { ServerChannel.GQL_EXECUTOR_CONSUMER_GROUP, executorChannel ) - console.log(`\nπŸ’§πŸ’§πŸ’§ Server ID: ${SERVER_ID}. Ready for GraphQL Execution πŸ’§πŸ’§πŸ’§`) + Logger.log(`\nπŸ’§πŸ’§πŸ’§ Server ID: ${SERVER_ID}. Ready for GraphQL Execution πŸ’§πŸ’§πŸ’§`) for await (const message of incomingStream) { // don't await the call below so this instance can immediately call incomingStream.next() diff --git a/packages/server/billing/debug.ts b/packages/server/billing/debug.ts index 75e83761934..606f1574c73 100644 --- a/packages/server/billing/debug.ts +++ b/packages/server/billing/debug.ts @@ -1,11 +1,12 @@ // call with yarn sucrase-node billing/debug.ts import '../../../scripts/webpack/utils/dotenv' import {getStripeManager} from '../utils/stripe' +import {Logger} from '../utils/Logger' const doDebugStuff = async () => { const manager = getStripeManager() const res = await manager.updateSubscriptionQuantity('foo', 39, 1597966749) - console.log('res', {res}) + Logger.log('res', {res}) } doDebugStuff() diff --git a/packages/server/dataloader/customLoaderMakers.ts b/packages/server/dataloader/customLoaderMakers.ts index 365f317ce0e..23259601f93 100644 --- a/packages/server/dataloader/customLoaderMakers.ts +++ b/packages/server/dataloader/customLoaderMakers.ts @@ -880,7 +880,7 @@ export const featureFlagByOwnerId = (parent: RootDataLoader) => { const missingFeatureNames = featureNames.filter((name) => !existingFeatureNameSet.has(name)) if (missingFeatureNames.length > 0) { - console.error( + Logger.error( `Feature flag name(s) not found: ${missingFeatureNames.join(', ')}. Add the feature flag name with the addFeatureFlag mutation.` ) } diff --git a/packages/server/debugJira.ts b/packages/server/debugJira.ts index c18aac926ff..68d53e9e4a3 100644 --- a/packages/server/debugJira.ts +++ b/packages/server/debugJira.ts @@ -1,6 +1,7 @@ // call with yarn sucrase-node debugJira.ts import '../../scripts/webpack/utils/dotenv' import AtlassianServerManager from './utils/AtlassianServerManager' +import {Logger} from './utils/Logger' const debugJira = async () => { // const cloudId = "foo" @@ -12,7 +13,7 @@ const debugJira = async () => { if (res instanceof Error) return const manager = new AtlassianServerManager(res.accessToken) const screens = await manager.getCloudNameLookup() - console.log(JSON.stringify(screens)) + Logger.log(JSON.stringify(screens)) } debugJira() diff --git a/packages/server/email/MailManagerDebug.ts b/packages/server/email/MailManagerDebug.ts index cce05a074c4..0ccccd57cd2 100644 --- a/packages/server/email/MailManagerDebug.ts +++ b/packages/server/email/MailManagerDebug.ts @@ -1,10 +1,11 @@ import fs from 'fs' +import {Logger} from '../utils/Logger' import MailManager, {MailManagerOptions} from './MailManager' export default class MailManagerDebug extends MailManager { async sendEmail(options: MailManagerOptions) { const {to, subject, body} = options - console.warn(`SENDING EMAIL + Logger.warn(`SENDING EMAIL To: ${to} Subject: ${subject} Body: ${body}`) @@ -17,7 +18,7 @@ export default class MailManagerDebug extends MailManager { const folder = '/tmp' fs.writeFileSync(`${folder}/${filename}`, html) // make it a link so you can click it in the terminal - console.warn(`Wrote email to file://${folder}/${encodeURIComponent(filename)}`) + Logger.warn(`Wrote email to file://${folder}/${encodeURIComponent(filename)}`) return true } } diff --git a/packages/server/fileStorage/LocalFileStoreManager.ts b/packages/server/fileStorage/LocalFileStoreManager.ts index 8f6efa0e0b5..8fab6626d9d 100644 --- a/packages/server/fileStorage/LocalFileStoreManager.ts +++ b/packages/server/fileStorage/LocalFileStoreManager.ts @@ -2,7 +2,9 @@ import fs from 'fs' import makeAppURL from 'parabol-client/utils/makeAppURL' import path from 'path' import appOrigin from '../appOrigin' +import {Logger} from '../utils/Logger' import FileStoreManager from './FileStoreManager' + export default class LocalFileStoreManager extends FileStoreManager { baseUrl = makeAppURL(appOrigin, 'self-hosted') constructor() { @@ -33,7 +35,7 @@ export default class LocalFileStoreManager extends FileStoreManager { } async putBuildFile() { - console.error( + Logger.error( 'Cannot call `putBuildFile` when using Local File Storage. The build files are already there' ) return '' diff --git a/packages/server/fileStorage/S3FileStoreManager.ts b/packages/server/fileStorage/S3FileStoreManager.ts index 9746ce38cb6..89c3a4a8957 100644 --- a/packages/server/fileStorage/S3FileStoreManager.ts +++ b/packages/server/fileStorage/S3FileStoreManager.ts @@ -4,6 +4,7 @@ import type {RetryErrorInfo, StandardRetryToken} from '@smithy/types' import {StandardRetryStrategy} from '@smithy/util-retry' import mime from 'mime-types' import path from 'path' +import {Logger} from '../utils/Logger' import FileStoreManager, {FileAssetDir} from './FileStoreManager' class CloudflareRetry extends StandardRetryStrategy { @@ -14,7 +15,7 @@ class CloudflareRetry extends StandardRetryStrategy { const status = errorInfo.error?.$response?.statusCode if (status && status >= 520 && status < 530) { const date = errorInfo.error?.$response?.headers?.date - console.log('Retrying after Cloudflare error', { + Logger.log('Retrying after Cloudflare error', { status, date: date && new Date(date).toISOString(), path: errorInfo.error?.$response?.body?.req?.path diff --git a/packages/server/graphql/composeResolvers.ts b/packages/server/graphql/composeResolvers.ts index 8652c420231..43e6f9b6cd0 100644 --- a/packages/server/graphql/composeResolvers.ts +++ b/packages/server/graphql/composeResolvers.ts @@ -13,6 +13,7 @@ import {defaultFieldResolver} from 'graphql' import {allow} from 'graphql-shield' import type {ShieldRule} from 'graphql-shield/dist/types' import hash from 'object-hash' +import {Logger} from '../utils/Logger' import {ResolverFn} from './private/resolverTypes' type Resolver = ResolverFn @@ -43,7 +44,7 @@ const wrapResolve = return res } } catch (err) { - console.log(err) + Logger.log(err) throw err } } diff --git a/packages/server/graphql/private/mutations/backupOrganization.ts b/packages/server/graphql/private/mutations/backupOrganization.ts index 0bdc6647248..7b6db2d24ac 100644 --- a/packages/server/graphql/private/mutations/backupOrganization.ts +++ b/packages/server/graphql/private/mutations/backupOrganization.ts @@ -6,6 +6,7 @@ import getProjectRoot from '../../../../../scripts/webpack/utils/getProjectRoot' import getKysely from '../../../postgres/getKysely' import getPg from '../../../postgres/getPg' import getPgConfig from '../../../postgres/getPgConfig' +import {Logger} from '../../../utils/Logger' import {MutationResolvers} from '../resolverTypes' const exec = util.promisify(childProcess.exec) @@ -23,7 +24,7 @@ const dumpPgDataToOrgBackupSchema = async (orgIds: string[]) => { .where('removedAt', 'is', null) .execute() const userIds = orgUsers.map(({userId}) => userId) - console.log({teamIds, userIds}) + Logger.log({teamIds, userIds}) // try { // // do all inserts here diff --git a/packages/server/graphql/private/queries/orgActivities.ts b/packages/server/graphql/private/queries/orgActivities.ts index ea97e24a00e..e0b1da0d381 100644 --- a/packages/server/graphql/private/queries/orgActivities.ts +++ b/packages/server/graphql/private/queries/orgActivities.ts @@ -1,5 +1,6 @@ import {sql} from 'kysely' import getKysely from '../../../postgres/getKysely' +import {Logger} from '../../../utils/Logger' import {OrgActivityRow, QueryResolvers} from '../resolverTypes' const orgActivities: QueryResolvers['orgActivities'] = async (_source, {startDate, endDate}) => { @@ -100,7 +101,7 @@ const orgActivities: QueryResolvers['orgActivities'] = async (_source, {startDat const rows = Object.values(combinedResults) return {rows} } catch (error) { - console.error('Error executing Org Activity Report:', error) + Logger.error('Error executing Org Activity Report:', error) return {error: {message: 'Error executing Org Activity Report'}} } } diff --git a/packages/server/hubSpot/backfillHubSpot.ts b/packages/server/hubSpot/backfillHubSpot.ts index 65ec029ffae..36ea442e9c2 100644 --- a/packages/server/hubSpot/backfillHubSpot.ts +++ b/packages/server/hubSpot/backfillHubSpot.ts @@ -1,6 +1,7 @@ // call with yarn sucrase-node hubSpot/backfillHubSpot.ts import '../../../scripts/webpack/utils/dotenv' import {getUsersByEmails} from '../postgres/queries/getUsersByEmails' +import {Logger} from '../utils/Logger' const contactKeys = { lastMetAt: 'last_met_at', @@ -49,7 +50,7 @@ const upsertHubspotContact = async ( ) if (!String(res.status).startsWith('2')) { const responseBody = await res.json() - console.error(`Failed to update HubSpot for ${email}: `, responseBody.message) + Logger.error(`Failed to update HubSpot for ${email}: `, responseBody.message) } } diff --git a/packages/server/jiraImagesHandler.ts b/packages/server/jiraImagesHandler.ts index 8aea88d2cdb..c02224dfe6d 100644 --- a/packages/server/jiraImagesHandler.ts +++ b/packages/server/jiraImagesHandler.ts @@ -3,6 +3,7 @@ import jiraPlaceholder from '../../static/images/illustrations/imageNotFound.png import sleep from '../client/utils/sleep' import uWSAsyncHandler from './graphql/uWSAsyncHandler' import getRedis, {RedisPipelineResponse} from './utils/getRedis' +import {Logger} from './utils/Logger' const getImageFromCache = async ( imgUrlHash: string, @@ -33,7 +34,7 @@ const servePlaceholderImage = async (res: HttpResponse) => { const res = await fetch(jiraPlaceholder) jiraPlaceholderBuffer = Buffer.from(await res.arrayBuffer()) } catch (e) { - console.error('Jira Placeholder image could not be fetched', e) + Logger.error('Jira Placeholder image could not be fetched', e) } } res.writeStatus('200').writeHeader('Content-Type', 'image/png').end(jiraPlaceholderBuffer) diff --git a/packages/server/listenHandler.ts b/packages/server/listenHandler.ts index 332c405224f..2a862ad028b 100644 --- a/packages/server/listenHandler.ts +++ b/packages/server/listenHandler.ts @@ -1,17 +1,18 @@ import {us_listen_socket} from 'uWebSockets.js' import getGraphQLExecutor from './utils/getGraphQLExecutor' +import {Logger} from './utils/Logger' import serverHealthChecker from './utils/serverHealthChecker' const listenHandler = (listenSocket: us_listen_socket) => { const PORT = Number(__PRODUCTION__ ? process.env.PORT : process.env.SOCKET_PORT) const SERVER_ID = process.env.SERVER_ID if (listenSocket) { - console.log(`\nπŸ”₯πŸ”₯πŸ”₯ Server ID: ${SERVER_ID}. Ready for Sockets: Port ${PORT} πŸ”₯πŸ”₯πŸ”₯`) + Logger.log(`\nπŸ”₯πŸ”₯πŸ”₯ Server ID: ${SERVER_ID}. Ready for Sockets: Port ${PORT} πŸ”₯πŸ”₯πŸ”₯`) getGraphQLExecutor().subscribe() // Cleaning on startup because shutdowns may be abrupt serverHealthChecker.cleanUserPresence() } else { - console.log(`❌❌❌ Port ${PORT} is in use! ❌❌❌`) + Logger.log(`❌❌❌ Port ${PORT} is in use! ❌❌❌`) } } diff --git a/packages/server/postgres/migrations/2024-11-27T00:50:24.390Z_taskContentToTipTap.ts b/packages/server/postgres/migrations/2024-11-27T00:50:24.390Z_taskContentToTipTap.ts index 527d4ec2c28..8738a6297d3 100644 --- a/packages/server/postgres/migrations/2024-11-27T00:50:24.390Z_taskContentToTipTap.ts +++ b/packages/server/postgres/migrations/2024-11-27T00:50:24.390Z_taskContentToTipTap.ts @@ -6,6 +6,7 @@ import StarterKit from '@tiptap/starter-kit' import {convertFromRaw, RawDraftContentState} from 'draft-js' import {Options, stateToHTML} from 'draft-js-export-html' import type {Kysely} from 'kysely' +import {Logger} from '../../utils/Logger' export const serverTipTapExtensions = [ StarterKit, @@ -46,7 +47,7 @@ const getNameFromEntity = (content: RawDraftContentState, userId: string) => { const {length, offset} = entityRange return text.slice(offset, offset + length) } - console.log('found unknown for', userId, JSON.stringify(content)) + Logger.log('found unknown for', userId, JSON.stringify(content)) return 'Unknown User' } @@ -95,7 +96,7 @@ export async function up(db: Kysely): Promise { .orderBy('id asc') .limit(1000) .execute() - console.log('converting tasks', i * 1000) + Logger.log('converting tasks', i * 1000) if (tasks.length === 0) break const updatePromises = [] as Promise[] for (const task of tasks) { @@ -112,7 +113,7 @@ export async function up(db: Kysely): Promise { .where('id', '=', id) .execute() } catch (e) { - console.log('GOT ERR', id, contentStr, e) + Logger.log('GOT ERR', id, contentStr, e) throw e } } diff --git a/packages/server/server.ts b/packages/server/server.ts index 668fb2f015c..dd938019ecb 100644 --- a/packages/server/server.ts +++ b/packages/server/server.ts @@ -22,6 +22,7 @@ import handleUpgrade from './socketHandlers/handleUpgrade' import SSEConnectionHandler from './sse/SSEConnectionHandler' import SSEPingHandler from './sse/SSEPingHandler' import staticFileHandler from './staticFileHandler' +import {Logger} from './utils/Logger' import SAMLHandler from './utils/SAMLHandler' tracer.init({ @@ -33,7 +34,7 @@ tracer.init({ tracer.use('ioredis').use('http').use('pg') process.on('SIGTERM', async (signal) => { - console.log( + Logger.log( `Server ID: ${process.env.SERVER_ID}. Kill signal received: ${signal}, starting graceful shutdown.` ) const RECONNECT_WINDOW = 60_000 // ms @@ -44,7 +45,7 @@ process.on('SIGTERM', async (signal) => { await handleDisconnect(connectionContext) }) ) - console.log(`Server ID: ${process.env.SERVER_ID}. Graceful shutdown complete, exiting.`) + Logger.log(`Server ID: ${process.env.SERVER_ID}. Graceful shutdown complete, exiting.`) process.exit() }) diff --git a/packages/server/staticFileHandler.ts b/packages/server/staticFileHandler.ts index 13da6a4e40e..2acf90b4cf8 100644 --- a/packages/server/staticFileHandler.ts +++ b/packages/server/staticFileHandler.ts @@ -1,5 +1,6 @@ import {HttpRequest, HttpResponse} from 'uWebSockets.js' import acceptsBrotli from './acceptsBrotli' +import {Logger} from './utils/Logger' import serveStatic from './utils/serveStatic' const ROUTE = '/static/' @@ -7,10 +8,10 @@ let hasWarned = false const staticFileHandler = async (res: HttpResponse, req: HttpRequest) => { if (__PRODUCTION__ && !hasWarned) { hasWarned = true - console.log( + Logger.log( 'Using NodeJS to serve static assets. This is slow! Your reverse proxy should redirect /static to a CDN' ) - console.log(req.getUrl()) + Logger.log(req.getUrl()) } const fileName = req.getUrl().slice(ROUTE.length) const servedStatic = serveStatic(res, fileName, acceptsBrotli(req)) diff --git a/packages/server/utils/getRedisOptions.ts b/packages/server/utils/getRedisOptions.ts index a728f22ba20..9285907352b 100644 --- a/packages/server/utils/getRedisOptions.ts +++ b/packages/server/utils/getRedisOptions.ts @@ -1,6 +1,7 @@ import {readFileSync} from 'fs' import path from 'node:path' import getProjectRoot from '../../../scripts/webpack/utils/getProjectRoot' +import {Logger} from './Logger' const getAbsPath = (maybeRelativePath: string) => { if (path.isAbsolute(maybeRelativePath)) return maybeRelativePath @@ -54,7 +55,7 @@ export const getRedisOptions = () => { const mode = getMode(tls, password) // Keep logs quiet if using default if (mode !== 'Unsecure') { - console.log(`Redis mode: ${mode}`) + Logger.log(`Redis mode: ${mode}`) } return {tls, password} } diff --git a/packages/server/utils/sendToSentry.ts b/packages/server/utils/sendToSentry.ts index 1403cee2c96..2fb6d24a1af 100644 --- a/packages/server/utils/sendToSentry.ts +++ b/packages/server/utils/sendToSentry.ts @@ -1,5 +1,6 @@ import * as Sentry from '@sentry/node' import {getUserById} from '../postgres/queries/getUsersByIds' +import {Logger} from './Logger' export interface SentryOptions { sampleRate?: number @@ -13,7 +14,7 @@ export interface SentryOptions { // Even though this is a promise we'll never need to await it, so we'll never need to worry about catching an error const sendToSentry = async (error: Error, options: SentryOptions = {}) => { - console.log('SEND TO SENTRY', error || JSON.stringify(error)) + Logger.log('SEND TO SENTRY', error || JSON.stringify(error)) const {sampleRate, tags, extras, userId, ip} = options if (sampleRate && Math.random() > sampleRate) return const fullUser = userId ? await getUserById(userId) : null diff --git a/packages/server/utils/serverHealthChecker.ts b/packages/server/utils/serverHealthChecker.ts index 6b5ad020530..86211b7b977 100644 --- a/packages/server/utils/serverHealthChecker.ts +++ b/packages/server/utils/serverHealthChecker.ts @@ -2,6 +2,7 @@ import sleep from '../../client/utils/sleep' import ServerAuthToken from '../database/types/ServerAuthToken' import {UserPresence} from '../graphql/private/mutations/connectSocket' import {disconnectQuery} from '../socketHandlers/handleDisconnect' +import {Logger} from './Logger' import RedisInstance from './RedisInstance' import publishInternalGQL from './publishInternalGQL' import sendToSentry from './sendToSentry' @@ -24,7 +25,7 @@ class ServerHealthChecker { this.publisher.publish(`socketServerPong:${remoteServerId}`, INSTANCE_ID) } else if (channel === `socketServerPong:${INSTANCE_ID}`) { if (!this.remoteSocketServers) { - console.error('unsolicited pong received before getLivingServers was called') + Logger.error('unsolicited pong received before getLivingServers was called') } else { this.remoteSocketServers.push(remoteServerId) } diff --git a/packages/server/utils/startMemwatch.js b/packages/server/utils/startMemwatch.js index 53bfe58be57..a585ac1e185 100644 --- a/packages/server/utils/startMemwatch.js +++ b/packages/server/utils/startMemwatch.js @@ -1,26 +1,27 @@ const memwatch = require('memwatch-next') const fs = require('fs') const path = require('path') +import {Logger} from './Logger' const startMemwatch = () => { - console.log('starting memwatch') + Logger.log('starting memwatch') memwatch.on('leak', (info) => { - console.error('Mem leak detected', info) + Logger.error('Mem leak detected', info) }) let snapStart let snapStop let heapDiff memwatch.on('stats', (stats) => { - console.log(stats.current_base) + Logger.log(stats.current_base) if (stats.current_base > 137062320 && stats.current_base < 139000000 && !snapStart) { snapStart = true - console.log('startMemwatch heapDiff') + Logger.log('startMemwatch heapDiff') heapDiff = new memwatch.HeapDiff() } if (stats.current_base > 145000000 && snapStart && !snapStop) { snapStop = true const end = heapDiff.end() - console.log('heapDiff end', end) + Logger.log('heapDiff end', end) const jsonPath = path.join(process.cwd(), 'leak.json') fs.writeFileSync(jsonPath, JSON.stringify(end, null, 2)) } diff --git a/packages/server/utils/stripe/StubStripeManager.ts b/packages/server/utils/stripe/StubStripeManager.ts index 2402030e6d1..074f2366892 100644 --- a/packages/server/utils/stripe/StubStripeManager.ts +++ b/packages/server/utils/stripe/StubStripeManager.ts @@ -1,5 +1,6 @@ import Stripe from 'stripe' import {toEpochSeconds} from '../epochTime' +import {Logger} from '../Logger' import StripeManager from './StripeManager' // using proxy to start gradual coverage of StripeManager @@ -25,7 +26,7 @@ export default function StubStripeManager() { } as unknown as Stripe.Subscription } default: - console.warn('StubStripeManager forwarding to real StripeManager', propKey) + Logger.warn('StubStripeManager forwarding to real StripeManager', propKey) return target[propKey] } } diff --git a/scripts/buildServers.js b/scripts/buildServers.js index 258c9dd76bf..a26329d7bfd 100644 --- a/scripts/buildServers.js +++ b/scripts/buildServers.js @@ -9,6 +9,7 @@ require('sucrase/register') const webpack = require('webpack') const waitForFileExists = require('./waitForFileExists').default const path = require('path') +const {Logger} = require('../packages/server/utils/Logger') const buildServers = async () => { const config = require('./webpack/dev.servers.config') @@ -17,11 +18,11 @@ const buildServers = async () => { if (!queryMapExists) throw Error('QueryMap Not Available. Run `yarn relay:build`') compiler.watch({aggregateTimeout: 100}, (err, stats) => { if (err) { - console.log('Webpack error:', err) + Logger.log('Webpack error:', err) } const errors = stats?.compilation?.errors ?? [] if (errors.length > 0) { - console.log('COMPILATION ERRORS:', errors) + Logger.log('COMPILATION ERRORS:', errors) } /* servers finished rebuilding */ }) diff --git a/scripts/generateGraphQLArtifacts.js b/scripts/generateGraphQLArtifacts.js index 20053fecd8a..02e3c051c89 100644 --- a/scripts/generateGraphQLArtifacts.js +++ b/scripts/generateGraphQLArtifacts.js @@ -5,6 +5,7 @@ const relayCompilerPath = require('relay-compiler') const cp = require('child_process') const runSchemaUpdater = require('./runSchemaUpdater').default const RelayPersistServer = require('./RelayPersistServer').default +const {Logger} = require('../packages/server/utils/Logger') const generateGraphQLArtifacts = async () => { await runSchemaUpdater(true) @@ -17,11 +18,11 @@ const generateGraphQLArtifacts = async () => { }) relayCompiler.stderr.pipe(process.stderr) }) - console.log('gen graphql artifacts start') + Logger.log('gen graphql artifacts start') await generate(codegenSchema) - console.log('codegen complete') + Logger.log('codegen complete') await runCompiler() - console.log('relay compiler complete') + Logger.log('relay compiler complete') persistServer.close() } diff --git a/scripts/prod.js b/scripts/prod.js index 58776184dc1..05a4fbcaa78 100644 --- a/scripts/prod.js +++ b/scripts/prod.js @@ -1,5 +1,6 @@ const generateGraphQLArtifacts = require('./generateGraphQLArtifacts') const cp = require('child_process') +const {Logger} = require('../packages/server/utils/Logger') const runChild = (cmd) => { return new Promise((resolve, reject) => { @@ -19,15 +20,15 @@ const runChild = (cmd) => { } const prod = async (isDeploy, noDeps) => { - console.log('πŸ™πŸ™πŸ™ Building Production Server πŸ™πŸ™πŸ™') + Logger.log('πŸ™πŸ™πŸ™ Building Production Server πŸ™πŸ™πŸ™') try { await generateGraphQLArtifacts() } catch (e) { - console.log('ERR generating artifacts', e) + Logger.log('ERR generating artifacts', e) process.exit(1) } - console.log('starting webpack build') + Logger.log('starting webpack build') try { await Promise.all([ runChild( @@ -38,7 +39,7 @@ const prod = async (isDeploy, noDeps) => { ) ]) } catch (e) { - console.log('error webpackifying', e) + Logger.log('error webpackifying', e) process.exit(1) } } diff --git a/scripts/runSchemaUpdater.ts b/scripts/runSchemaUpdater.ts index 4a8291f75d6..c5417c2dc9c 100644 --- a/scripts/runSchemaUpdater.ts +++ b/scripts/runSchemaUpdater.ts @@ -5,6 +5,7 @@ They are included in the build to minimize the number of webpack builds we perform */ import webpack from 'webpack' +import {Logger} from 'parabol-server/utils/Logger' const compileToolbox = async (ignoreErrors: boolean) => { return new Promise((resolve) => { @@ -12,11 +13,11 @@ const compileToolbox = async (ignoreErrors: boolean) => { const compiler = webpack(config) compiler.run((err, stats) => { if (err) { - console.log('Webpack error:', err) + Logger.log('Webpack error:', err) } const errors = stats?.compilation?.errors ?? [] if (!ignoreErrors && errors.length > 0) { - console.log('COMPILATION ERRORS:', errors) + Logger.log('COMPILATION ERRORS:', errors) } resolve() }) diff --git a/scripts/toolboxSrc/assignSURole.ts b/scripts/toolboxSrc/assignSURole.ts index 7fab627ca59..dadcc500a8a 100644 --- a/scripts/toolboxSrc/assignSURole.ts +++ b/scripts/toolboxSrc/assignSURole.ts @@ -1,5 +1,6 @@ import getPg from '../../packages/server/postgres/getPg' import yargs from 'yargs' +import {Logger} from '../../packages/server/utils/Logger' async function assignSURole() { const argv = await yargs(process.argv.slice(2)) @@ -26,15 +27,15 @@ async function assignSURole() { const pg = getPg() if (argv.removeAll) { const res = await pg.query(`UPDATE "User" SET rol = null WHERE rol = 'su' RETURNING email`) - console.log('Removed all', res.rows) + Logger.log('Removed all', res.rows) } if (argv.add) { const res = await pg.query(`UPDATE "User" SET rol = 'su' WHERE email = ANY ($1) RETURNING email`, [argv.add]) - console.log('Added', res.rows) + Logger.log('Added', res.rows) } if (argv.remove) { const res = await pg.query('UPDATE "User" SET rol = null WHERE email = ANY ($1) RETURNING email', [argv.remove]) - console.log('Removed', res.rows) + Logger.log('Removed', res.rows) } await pg.end() } diff --git a/scripts/toolboxSrc/pgEnsureExtensions.ts b/scripts/toolboxSrc/pgEnsureExtensions.ts index 3fcf9ea4f71..d07a35e8058 100644 --- a/scripts/toolboxSrc/pgEnsureExtensions.ts +++ b/scripts/toolboxSrc/pgEnsureExtensions.ts @@ -1,14 +1,15 @@ import {sql} from 'kysely' import getKysely from '../../packages/server/postgres/getKysely' +import {Logger} from '../../packages/server/utils/Logger' export default async () => { - console.log('πŸ”© Postgres Extension Checks Started') + Logger.log('πŸ”© Postgres Extension Checks Started') if (process.env.POSTGRES_USE_PGVECTOR === 'true') { - console.log(' pgvector') + Logger.log(' pgvector') const pg = getKysely() await sql`CREATE EXTENSION IF NOT EXISTS "vector";`.execute(pg) } else { - console.log(' pgvector: skipping check (POSTGRES_USE_PGVECTOR !== true)') + Logger.log(' pgvector: skipping check (POSTGRES_USE_PGVECTOR !== true)') } - console.log('πŸ”© Postgres Extension Checks Completed') + Logger.log('πŸ”© Postgres Extension Checks Completed') } diff --git a/scripts/toolboxSrc/pgRestore.ts b/scripts/toolboxSrc/pgRestore.ts index beee0e2de58..fcfedfafb91 100644 --- a/scripts/toolboxSrc/pgRestore.ts +++ b/scripts/toolboxSrc/pgRestore.ts @@ -5,6 +5,7 @@ import {promisify} from 'util' import getPg from '../../packages/server/postgres/getPg' import getPgConfig from '../../packages/server/postgres/getPgConfig' import getProjectRoot from '../webpack/utils/getProjectRoot' +import {Logger} from '../../packages/server/utils/Logger' async function pgRestore() { const exec = promisify(cp.exec) @@ -22,7 +23,7 @@ async function pgRestore() { const requiredFiles = [SCHEMA_ROOT, DATA_ROOT] for (const file of requiredFiles) { if (!fs.existsSync(file)) { - console.log(`${file} does not exist`) + Logger.log(`${file} does not exist`) return } } diff --git a/scripts/toolboxSrc/primeIntegrations.ts b/scripts/toolboxSrc/primeIntegrations.ts index fd10c034ec0..4d2e1cc47f4 100644 --- a/scripts/toolboxSrc/primeIntegrations.ts +++ b/scripts/toolboxSrc/primeIntegrations.ts @@ -1,5 +1,6 @@ import getPg from '../../packages/server/postgres/getPg' import upsertIntegrationProvider from '../../packages/server/postgres/queries/upsertIntegrationProvider' +import {Logger} from '../../packages/server/utils/Logger' const upsertGlobalIntegrationProvidersFromEnv = async () => { const providers = [ @@ -40,9 +41,9 @@ const upsertGlobalIntegrationProvidersFromEnv = async () => { } const primeIntegrations = async () => { - console.log('⛓️ Prime Integrationgs Started') + Logger.log('⛓️ Prime Integrationgs Started') await upsertGlobalIntegrationProvidersFromEnv() - console.log('⛓️ Prime Integrations Complete') + Logger.log('⛓️ Prime Integrations Complete') } export default primeIntegrations diff --git a/scripts/toolboxSrc/pushToCDN.ts b/scripts/toolboxSrc/pushToCDN.ts index 536a38c1536..6ff207e3123 100644 --- a/scripts/toolboxSrc/pushToCDN.ts +++ b/scripts/toolboxSrc/pushToCDN.ts @@ -2,6 +2,7 @@ import fs from 'fs' import getFileStoreManager from 'parabol-server/fileStorage/getFileStoreManager' import path from 'path' import getProjectRoot from '../webpack/utils/getProjectRoot' +import {Logger} from 'parabol-server/utils/Logger' const PROJECT_ROOT = getProjectRoot() @@ -12,7 +13,7 @@ const pushClientAssetsToCDN = async () => { const fileStoreManager = getFileStoreManager() const localClientAssetsDir = path.join(PROJECT_ROOT, 'build') if (process.env.FILE_STORE_PROVIDER === 'local') { - console.log('⛅️ Using Local File Store for client assets. Skipping...') + Logger.log('⛅️ Using Local File Store for client assets. Skipping...') return } @@ -29,7 +30,7 @@ const pushClientAssetsToCDN = async () => { }) ) } - console.log(`⛅️ Uploaded ${dirEnts.length} client assets to CDN`) + Logger.log(`⛅️ Uploaded ${dirEnts.length} client assets to CDN`) } const pushServerAssetsToCDN = async () => { @@ -56,7 +57,7 @@ const pushServerAssetsToCDN = async () => { const buffer = await fs.promises.readFile(path.join(localServerAssetsDir, filename)) const {name, ext} = path.parse(filename) const url = await fileStoreManager.putTemplateIllustration(buffer, 'aGhostOrg', ext, name) - console.log(`⛅️ Uploaded template ${filename} to ${url}`) + Logger.log(`⛅️ Uploaded template ${filename} to ${url}`) return true } @@ -69,7 +70,7 @@ const pushServerAssetsToCDN = async () => { if (exists) return false const buffer = await fs.promises.readFile(path.join(localServerAssetsDir, filename)) const url = await fileStoreManager.putBuildFile(buffer, targetObject) - console.log(`⛅️ Uploaded server asset ${targetObject} to ${url}`) + Logger.log(`⛅️ Uploaded server asset ${targetObject} to ${url}`) return true } @@ -92,15 +93,15 @@ const pushServerAssetsToCDN = async () => { ) } - console.log(`⛅️ Server upload complete. Pushed ${pushed} assets to CDN`) + Logger.log(`⛅️ Server upload complete. Pushed ${pushed} assets to CDN`) } const pushToCDN = async () => { - console.log('⛅️ Push to CDN Started') + Logger.log('⛅️ Push to CDN Started') // Perform in serial to guarantee no more than 50 uploads at a time await pushClientAssetsToCDN() await pushServerAssetsToCDN() - console.log('⛅️ Push to CDN Complete') + Logger.log('⛅️ Push to CDN Complete') } // If called via CLI diff --git a/scripts/toolboxSrc/setIsEnterprise.ts b/scripts/toolboxSrc/setIsEnterprise.ts index 9fe23b5cfeb..7947a6979c4 100644 --- a/scripts/toolboxSrc/setIsEnterprise.ts +++ b/scripts/toolboxSrc/setIsEnterprise.ts @@ -1,5 +1,6 @@ import getKysely from 'parabol-server/postgres/getKysely' -import {defaultTier} from '../../packages/server/utils/defaultTier' +import {defaultTier} from 'parabol-server/utils/defaultTier' +import {Logger} from 'parabol-server/utils/Logger' export default async function setIsEnterprise() { if (defaultTier !== 'enterprise') { @@ -16,7 +17,7 @@ export default async function setIsEnterprise() { pg.updateTable('Team').set({tier: 'enterprise'}).execute() ]) - console.log('Finished updating tiers.') + Logger.log('Finished updating tiers.') await pg.destroy() process.exit()