From 26dc8e43bc5d19efb4b34bbabf87668cf9df6272 Mon Sep 17 00:00:00 2001 From: Thassio Victor Date: Mon, 6 Sep 2021 18:26:25 -0300 Subject: [PATCH 01/15] [IMPROVE][APPS] Return task ids when using the scheduler api (#23023) * Return task ids when using the scheduler api * Fix indentation * Adjustments based on linter hints * Remove unnecessary `$or` from mongodb query * Update Apps-Engine version * Fix linter problem * Send the job id to the processor context in the app * Add bson library --- app/apps/server/bridges/scheduler.ts | 50 ++++++++++++++++++---------- package-lock.json | 14 ++++++-- package.json | 3 +- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/app/apps/server/bridges/scheduler.ts b/app/apps/server/bridges/scheduler.ts index 0676178c84de..698931a25be2 100644 --- a/app/apps/server/bridges/scheduler.ts +++ b/app/apps/server/bridges/scheduler.ts @@ -1,4 +1,5 @@ import Agenda from 'agenda'; +import { ObjectID } from 'bson'; import { MongoInternals } from 'meteor/mongo'; import { StartupType, @@ -10,13 +11,15 @@ import { SchedulerBridge } from '@rocket.chat/apps-engine/server/bridges/Schedul import { AppServerOrchestrator } from '../orchestrator'; -function _callProcessor(processor: Function): (job: { attrs?: { data: object } }) => void { +function _callProcessor(processor: Function): (job: Agenda.Job) => void { return (job): void => { const data = job?.attrs?.data || {}; // This field is for internal use, no need to leak to app processor delete (data as any).appId; + data.jobId = job.attrs._id.toString(); + return processor(data); }; } @@ -68,10 +71,10 @@ export class AppSchedulerBridge extends SchedulerBridge { * @param {Array.} processors An array of processors * @param {string} appId * - * @returns Promise + * @returns {string[]} List of task ids run at startup, or void no startup run is set */ - protected async registerProcessors(processors: Array = [], appId: string): Promise { - const runAfterRegister: Promise[] = []; + protected async registerProcessors(processors: Array = [], appId: string): Promise> { + const runAfterRegister: Promise[] = []; this.orch.debugLog(`The App ${ appId } is registering job processors`, processors); processors.forEach(({ id, processor, startupSetting }: IProcessor) => { this.scheduler.define(id, _callProcessor(processor)); @@ -82,10 +85,10 @@ export class AppSchedulerBridge extends SchedulerBridge { switch (startupSetting.type) { case StartupType.ONETIME: - runAfterRegister.push(this.scheduleOnceAfterRegister({ id, when: startupSetting.when, data: startupSetting.data }, appId)); + runAfterRegister.push(this.scheduleOnceAfterRegister({ id, when: startupSetting.when, data: startupSetting.data }, appId) as Promise); break; case StartupType.RECURRING: - runAfterRegister.push(this.scheduleRecurring({ id, interval: startupSetting.interval, skipImmediate: startupSetting.skipImmediate, data: startupSetting.data }, appId)); + runAfterRegister.push(this.scheduleRecurring({ id, interval: startupSetting.interval, skipImmediate: startupSetting.skipImmediate, data: startupSetting.data }, appId) as Promise); break; default: this.orch.getRocketChatLogger().error(`Invalid startup setting type (${ String((startupSetting as any).type) }) for the processor ${ id }`); @@ -94,7 +97,7 @@ export class AppSchedulerBridge extends SchedulerBridge { }); if (runAfterRegister.length) { - await Promise.all(runAfterRegister); + return Promise.all(runAfterRegister) as Promise>; } } @@ -107,22 +110,23 @@ export class AppSchedulerBridge extends SchedulerBridge { * @param {Object} [job.data] An optional object that is passed to the processor * @param {string} appId * - * @returns Promise + * @returns {string} taskid */ - protected async scheduleOnce(job: IOnetimeSchedule, appId: string): Promise { - this.orch.debugLog(`The App ${ appId } is scheduling an onetime job`, job); + protected async scheduleOnce({ id, when, data }: IOnetimeSchedule, appId: string): Promise { + this.orch.debugLog(`The App ${ appId } is scheduling an onetime job (processor ${ id })`); try { await this.startScheduler(); - await this.scheduler.schedule(job.when, job.id, this.decorateJobData(job.data, appId)); + const job = await this.scheduler.schedule(when, id, this.decorateJobData(data, appId)); + return job.attrs._id.toString(); } catch (e) { this.orch.getRocketChatLogger().error(e); } } - private async scheduleOnceAfterRegister(job: IOnetimeSchedule, appId: string): Promise { + private async scheduleOnceAfterRegister(job: IOnetimeSchedule, appId: string): Promise { const scheduledJobs = await this.scheduler.jobs({ name: job.id, type: 'normal' }); if (!scheduledJobs.length) { - await this.scheduleOnce(job, appId); + return this.scheduleOnce(job, appId); } } @@ -136,13 +140,14 @@ export class AppSchedulerBridge extends SchedulerBridge { * @param {Object} [job.data] An optional object that is passed to the processor * @param {string} appId * - * @returns Promise + * @returns {string} taskid */ - protected async scheduleRecurring({ id, interval, skipImmediate = false, data }: IRecurringSchedule, appId: string): Promise { - this.orch.debugLog(`The App ${ appId } is scheduling a recurring job`, id); + protected async scheduleRecurring({ id, interval, skipImmediate = false, data }: IRecurringSchedule, appId: string): Promise { + this.orch.debugLog(`The App ${ appId } is scheduling a recurring job (processor ${ id })`); try { await this.startScheduler(); - await this.scheduler.every(interval, id, this.decorateJobData(data, appId), { skipImmediate }); + const job = await this.scheduler.every(interval, id, this.decorateJobData(data, appId), { skipImmediate }); + return job.attrs._id.toString(); } catch (e) { this.orch.getRocketChatLogger().error(e); } @@ -159,8 +164,17 @@ export class AppSchedulerBridge extends SchedulerBridge { protected async cancelJob(jobId: string, appId: string): Promise { this.orch.debugLog(`The App ${ appId } is canceling a job`, jobId); await this.startScheduler(); + + let cancelQuery; + try { + cancelQuery = { _id: new ObjectID(jobId.split('_')[0]) }; + } catch (jobDocIdError) { + // it is not a valid objectid, so it won't try to cancel by document id + cancelQuery = { name: jobId }; + } + try { - await this.scheduler.cancel({ name: jobId }); + await this.scheduler.cancel(cancelQuery); } catch (e) { this.orch.getRocketChatLogger().error(e); } diff --git a/package-lock.json b/package-lock.json index d7afe2fbff51..a17f1185612d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5152,9 +5152,9 @@ } }, "@rocket.chat/apps-engine": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.27.1.tgz", - "integrity": "sha512-cdOfcd83mRILvT6c7nDoIUadGpqnyPMPpiKZa9ZPsERSZmImkZ/UlHlmNMMf/jZ3GQt34vgcY187CUNN7XMZ/g==", + "version": "1.28.0-alpha.5370", + "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.28.0-alpha.5370.tgz", + "integrity": "sha512-OGfjeX8cxPjreG34AioFCtEA6eJRRqoay6WddZ2goFxQjBVWQzwvmuzXKNZt/hclTjRZbBVu0yKscJhlW1ijug==", "requires": { "adm-zip": "^0.4.9", "cryptiles": "^4.1.3", @@ -14393,6 +14393,14 @@ "node-int64": "^0.4.0" } }, + "bson": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.5.1.tgz", + "integrity": "sha512-XqFP74pbTVLyLy5KFxVfTUyRrC1mgOlmu/iXHfXqfCKT59jyP9lwbotGfbN59cHBRbJSamZNkrSopjv+N0SqAA==", + "requires": { + "buffer": "^5.6.0" + } + }, "buffer": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", diff --git a/package.json b/package.json index 6eff91fbf30d..a32b54d63747 100644 --- a/package.json +++ b/package.json @@ -158,7 +158,7 @@ "@nivo/heatmap": "0.73.0", "@nivo/line": "0.62.0", "@nivo/pie": "0.73.0", - "@rocket.chat/apps-engine": "1.27.1", + "@rocket.chat/apps-engine": "1.28.0-alpha.5370", "@rocket.chat/css-in-js": "^0.29.0", "@rocket.chat/emitter": "^0.29.0", "@rocket.chat/fuselage": "^0.29.0", @@ -185,6 +185,7 @@ "bcrypt": "^5.0.1", "blockstack": "19.3.0", "body-parser": "1.19.0", + "bson": "^4.5.1", "bunyan": "^1.8.15", "busboy": "^0.3.1", "bytebuffer": "5.0.1", From 2dcc1f30f6f7b46862d01dab9326d831f9afee49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Thom=C3=A9?= <38537062+g-thome@users.noreply.github.com> Date: Mon, 6 Sep 2021 20:52:43 -0300 Subject: [PATCH 02/15] Regression: Auth banner for EE (#23091) * add extra verification before creating banner * dismiss banners wrongly emitted for enterprise deploys * remove from CE servers that don't have customOAuthEnabled * fix GE * remove console log * await settings find * ldap and saml Co-authored-by: Gabriel Casals <83978645+casalsgh@users.noreply.github.com> --- server/startup/migrations/index.js | 1 + server/startup/migrations/v231.ts | 4 ++- server/startup/migrations/v232.ts | 40 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 server/startup/migrations/v232.ts diff --git a/server/startup/migrations/index.js b/server/startup/migrations/index.js index 89f96f56ed11..3b9354a6a27c 100644 --- a/server/startup/migrations/index.js +++ b/server/startup/migrations/index.js @@ -228,4 +228,5 @@ import './v228'; import './v229'; import './v230'; import './v231'; +import './v232'; import './xrun'; diff --git a/server/startup/migrations/v231.ts b/server/startup/migrations/v231.ts index e0ae365111bc..3b745e6b804a 100644 --- a/server/startup/migrations/v231.ts +++ b/server/startup/migrations/v231.ts @@ -6,6 +6,7 @@ import { BannerPlatform } from '../../../definition/IBanner'; import { Banner } from '../../sdk'; import { settings } from '../../../app/settings/server'; import { Settings } from '../../../app/models/server'; +import { isEnterprise } from '../../../ee/app/license/server'; Migrations.add({ version: 231, @@ -21,7 +22,8 @@ Migrations.add({ const isAuthServiceEnabled = LDAPEnabled || SAMLEnabled || CustomOauthEnabled; - if (!isAuthServiceEnabled) { + const isEE = isEnterprise(); + if (!isAuthServiceEnabled || isEE) { return; } diff --git a/server/startup/migrations/v232.ts b/server/startup/migrations/v232.ts new file mode 100644 index 000000000000..abe4113fb94a --- /dev/null +++ b/server/startup/migrations/v232.ts @@ -0,0 +1,40 @@ +import { Migrations } from '../../../app/migrations/server'; +import { isEnterprise } from '../../../ee/app/license/server'; +import { Users, Settings } from '../../../app/models/server/raw'; +import { Banner } from '../../sdk'; +import { BannerPlatform } from '../../../definition/IBanner'; +import { IUser } from '../../../definition/IUser'; +import { settings } from '../../../app/settings/server'; + +Migrations.add({ + version: 232, + up() { + const query = { + _id: { $in: [/^Accounts_OAuth_Custom-?([^-_]+)$/] }, + value: true, + }; + + const isCustomOAuthEnabled = !!Promise.await(Settings.findOne(query)); + const LDAPEnabled = settings.get('LDAP_Enable'); + const SAMLEnabled = settings.get('SAML_Custom_Default'); + + const isEE = isEnterprise(); + + if (!isEE && (isCustomOAuthEnabled || LDAPEnabled || SAMLEnabled)) { + return; + } + + const admins = Promise.await(Users.find({ roles: 'admin' }, {}).toArray()); + + const banners = admins.map((a) => Promise.await(Banner.getNewBannersForUser(a._id, BannerPlatform.Web))).flat(); + const msg = 'Please notice that after the next release (4.0) advanced functionalities of LDAP, SAML, and Custom Oauth will be available only in Enterprise Edition and Gold plan. Check the official announcement for more info: https://go.rocket.chat/i/authentication-changes'; + // @ts-ignore + const authBanner = banners.find((b) => b.view.blocks[0].text.text === msg); + + if (!authBanner) { + return; + } + + admins.map((a) => Banner.dismiss(a._id, authBanner._id)); + }, +}); From 9ae05463852458b08fe68033561ee42209d8172f Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Wed, 8 Sep 2021 14:51:54 -0300 Subject: [PATCH 03/15] [IMPROVE] Change log format to JSON (#22975) --- app/api/server/api.js | 58 ++-- app/api/server/v1/misc.js | 2 +- app/apps/server/communication/uikit.js | 5 +- app/apps/server/communication/websockets.js | 5 +- .../server/lib/logLoginAttempts.ts | 3 +- .../server/lib/restrictLoginAttempts.ts | 2 - app/autotranslate/server/deeplTranslate.js | 2 +- app/autotranslate/server/googleTranslate.js | 2 +- app/autotranslate/server/logger.js | 12 +- app/autotranslate/server/msTranslate.js | 6 +- app/bigbluebutton/server/bigbluebutton-api.js | 16 +- app/blockstack/server/loginHandler.js | 2 +- app/callbacks/lib/callbacks.js | 2 +- app/cas/server/cas_rocketchat.js | 2 +- app/chatpal-search/server/provider/index.js | 8 +- .../server/provider/provider.js | 4 +- app/chatpal-search/server/utils/logger.js | 2 +- .../server/functions/connectWorkspace.js | 5 +- .../functions/finishOAuthAuthorization.js | 5 +- .../functions/getUserCloudAccessToken.js | 7 +- .../getWorkspaceAccessTokenWithScope.js | 7 +- .../server/functions/getWorkspaceLicense.js | 5 +- .../functions/startRegisterWorkspace.js | 5 +- app/cloud/server/functions/syncWorkspace.js | 5 +- app/cloud/server/functions/userLogout.js | 5 +- app/cors/server/cors.js | 2 +- app/crowd/server/crowd.js | 2 +- .../server/custom_oauth_server.js | 2 +- app/custom-oauth/server/oauth_helpers.js | 2 +- .../server/startup/custom-sounds.js | 3 +- .../server/startup/emoji-custom.js | 5 +- app/federation/server/endpoints/dispatch.js | 12 +- .../server/endpoints/requestFromLatest.js | 4 +- app/federation/server/endpoints/users.js | 6 +- app/federation/server/handler/index.js | 10 +- .../server/hooks/afterAddedToRoom.js | 6 +- .../server/hooks/afterCreateDirectRoom.js | 6 +- .../server/hooks/afterCreateRoom.js | 6 +- .../server/hooks/afterDeleteMessage.js | 4 +- app/federation/server/hooks/afterLeaveRoom.js | 6 +- app/federation/server/hooks/afterMuteUser.js | 4 +- .../server/hooks/afterRemoveFromRoom.js | 6 +- .../server/hooks/afterSaveMessage.js | 4 +- .../server/hooks/afterSetReaction.js | 6 +- .../server/hooks/afterUnmuteUser.js | 4 +- .../server/hooks/afterUnsetReaction.js | 6 +- .../server/hooks/beforeDeleteRoom.js | 6 +- app/federation/server/lib/crypt.js | 6 +- app/federation/server/lib/dns.js | 30 +- app/federation/server/lib/http.js | 8 +- app/federation/server/lib/logger.js | 18 +- app/federation/server/startup/settings.js | 4 +- app/file-upload/server/config/AmazonS3.js | 3 +- .../server/config/GoogleStorage.js | 5 +- app/file-upload/server/config/Webdav.js | 3 +- .../server/config/_configUploadStorage.js | 5 +- app/file-upload/server/lib/FileUpload.js | 9 +- app/file-upload/server/lib/proxy.js | 6 +- .../server/methods/sendFileMessage.ts | 3 +- app/file-upload/ufs/AmazonS3/server.js | 6 +- app/file-upload/ufs/GoogleStorage/server.js | 4 +- app/file-upload/ufs/Webdav/server.js | 3 +- app/google-vision/server/googlevision.js | 7 +- app/iframe-login/server/iframe_server.js | 2 - app/importer-csv/server/importer.js | 2 +- .../server/importer.js | 2 +- .../server/importer.js | 3 +- app/importer-slack/server/importer.js | 6 +- app/importer/server/classes/ImporterBase.js | 2 +- .../server/startup/setImportsToInvalid.js | 5 +- app/integrations/server/api/api.js | 50 ++- app/integrations/server/lib/triggerHandler.js | 83 ++--- app/integrations/server/logger.js | 10 +- app/irc/server/irc-bridge/index.js | 12 +- .../irc-bridge/localHandlers/onSaveMessage.js | 3 +- app/irc/server/servers/RFC2813/index.js | 14 +- app/ldap/server/ldap.js | 85 +++-- app/ldap/server/loginHandler.js | 2 +- app/ldap/server/sync.js | 4 +- app/ldap/server/testConnection.js | 7 +- .../server/functions/processWebhookMessage.js | 5 +- app/lib/server/functions/sendMessage.js | 5 +- app/lib/server/functions/setUserAvatar.js | 15 +- app/lib/server/functions/setUsername.js | 3 +- app/lib/server/functions/updateMessage.js | 9 +- app/lib/server/index.js | 1 - app/lib/server/lib/configLogger.js | 19 -- app/lib/server/lib/debug.js | 63 ++-- .../server/lib/interceptDirectReplyEmails.js | 15 +- app/lib/server/lib/processDirectEmail.js | 11 +- app/lib/server/methods/sendMessage.js | 2 +- app/lib/server/startup/oAuthServicesUpdate.js | 10 +- app/lib/server/startup/rateLimiter.js | 4 +- app/lib/server/startup/settings.js | 8 - .../startup/settingsOnLoadDirectReply.js | 25 +- app/lib/server/startup/settingsOnLoadSMTP.js | 5 +- app/livechat/imports/server/rest/facebook.js | 2 +- app/livechat/imports/server/rest/sms.js | 2 +- app/livechat/server/hooks/RDStation.js | 3 +- app/livechat/server/lib/Helper.js | 2 +- app/livechat/server/lib/Livechat.js | 16 +- app/livechat/server/lib/routing/External.js | 3 +- app/livechat/server/methods/facebook.js | 3 +- .../server/methods/getAgentOverviewData.js | 2 +- .../server/methods/getAnalyticsChartData.js | 2 +- .../methods/getAnalyticsOverviewData.js | 2 +- app/livechat/server/methods/webhookTest.js | 3 +- app/logger/server/index.js | 7 +- app/logger/server/server.js | 321 ------------------ app/logger/server/streamer.js | 53 +-- .../server/functions/sendMail.js | 7 +- .../server/functions/unsubscribe.js | 9 +- app/message-mark-as-unread/server/logger.js | 7 +- .../server/unreadMessages.js | 4 +- app/meteor-accounts-saml/server/lib/SAML.ts | 9 +- app/meteor-accounts-saml/server/lib/Utils.ts | 2 +- .../server/lib/parsers/LogoutRequest.ts | 2 +- .../server/lib/parsers/Response.ts | 6 +- .../server/lib/settings.ts | 3 +- app/meteor-accounts-saml/server/listener.ts | 5 +- .../server/loginHandler.ts | 5 +- .../server/methods/samlLogout.ts | 4 +- app/meteor-accounts-saml/server/startup.ts | 2 +- app/metrics/server/lib/collectMetrics.js | 13 +- app/migrations/server/migrations.js | 55 +-- app/models/server/models/Rooms.js | 1 + app/models/server/models/Users.js | 1 - app/models/server/models/_BaseDb.js | 3 +- app/nextcloud/server/addWebdavServer.js | 7 +- .../server/NotificationQueue.ts | 5 +- app/oembed/server/providers.js | 5 +- app/oembed/server/server.js | 3 +- app/push/server/apn.js | 20 +- app/push/server/gcm.js | 8 +- app/push/server/logger.js | 3 +- app/push/server/push.js | 4 +- app/search/server/logger/logger.js | 2 +- app/search/server/service/providerService.js | 4 +- app/settings/server/functions/settings.ts | 3 +- app/slackbridge/server/RocketAdapter.js | 46 +-- app/slackbridge/server/SlackAdapter.js | 92 ++--- app/slackbridge/server/logger.js | 15 +- app/slackbridge/server/slackbridge.js | 16 +- app/sms/server/services/mobex.js | 7 +- app/sms/server/services/twilio.js | 5 +- app/sms/server/services/voxtelesys.js | 5 +- app/theme/server/server.js | 12 +- app/utils/lib/templateVarHandler.js | 4 +- app/videobridge/server/methods/bbb.js | 15 +- .../server/methods/jitsiSetTimeout.js | 2 +- .../server/methods/uploadFileToWebdav.ts | 2 +- .../hooks/afterForwardChatToDepartment.js | 10 +- .../server/hooks/afterInquiryQueued.ts | 6 +- .../server/hooks/afterOnHold.ts | 8 +- .../server/hooks/afterOnHoldChatResumed.ts | 6 +- .../server/hooks/afterReturnRoomAsInquiry.ts | 4 +- .../server/hooks/afterTakeInquiry.js | 8 +- .../hooks/applyDepartmentRestrictions.ts | 6 +- .../applySimultaneousChatsRestrictions.ts | 6 +- .../hooks/beforeForwardRoomToDepartment.js | 10 +- .../server/hooks/beforeNewInquiry.js | 10 +- .../server/hooks/beforeRoutingChat.js | 12 +- .../hooks/checkAgentBeforeTakeInquiry.js | 16 +- .../server/hooks/onAgentAssignmentFailed.ts | 14 +- .../onLoadForwardDepartmentRestrictions.js | 8 +- .../server/hooks/scheduleAutoTransfer.ts | 10 +- .../livechat-enterprise/server/lib/Helper.js | 12 +- .../server/lib/LivechatEnterprise.js | 22 +- .../livechat-enterprise/server/lib/logger.js | 16 +- ee/app/models/server/models/LivechatRooms.js | 4 +- ee/app/models/server/models/LivechatUnit.js | 6 +- ee/app/models/server/raw/LivechatRooms.js | 4 +- ee/server/services/ecdh-proxy/lib/server.ts | 4 +- ee/server/services/package-lock.json | 190 ++++++++++- ee/server/services/package.json | 3 + .../server/lib/ReadReceipt.js | 3 +- package-lock.json | 172 +++++++++- package.json | 3 + .../EmailInbox/EmailInbox_Incoming.ts | 4 +- server/lib/logger/Logger.ts | 97 ++++++ server/lib/logger/getPino.ts | 25 ++ server/lib/logger/logLevel.ts | 7 + server/lib/logger/logPayloads.ts | 33 ++ server/lib/logger/showBox.ts | 42 +++ server/lib/logger/startup.ts | 8 + server/lib/logger/system.ts | 3 + server/lib/sendMessagesToAdmins.js | 3 +- server/main.js | 1 + server/methods/sendForgotPasswordEmail.js | 3 +- .../notifications/notifications.module.ts | 29 +- server/modules/streamer/streamer.module.ts | 6 +- server/services/nps/getAndCreateNpsSurvey.ts | 5 +- server/services/nps/sendNpsResults.ts | 3 +- server/startup/migrations/index.js | 1 + server/startup/migrations/v099.js | 7 +- server/startup/migrations/v233.ts | 12 + server/startup/serverRunning.js | 12 +- server/stream/streamBroadcast.js | 71 ++-- 198 files changed, 1437 insertions(+), 1253 deletions(-) delete mode 100644 app/lib/server/lib/configLogger.js delete mode 100644 app/logger/server/server.js create mode 100644 server/lib/logger/Logger.ts create mode 100644 server/lib/logger/getPino.ts create mode 100644 server/lib/logger/logLevel.ts create mode 100644 server/lib/logger/logPayloads.ts create mode 100644 server/lib/logger/showBox.ts create mode 100644 server/lib/logger/startup.ts create mode 100644 server/lib/logger/system.ts create mode 100644 server/startup/migrations/v233.ts diff --git a/app/api/server/api.js b/app/api/server/api.js index 34d34aadf09b..c492b1a6e81b 100644 --- a/app/api/server/api.js +++ b/app/api/server/api.js @@ -7,21 +7,15 @@ import { Restivus } from 'meteor/nimble:restivus'; import { RateLimiter } from 'meteor/rate-limit'; import _ from 'underscore'; -import { Logger } from '../../logger'; -import { settings } from '../../settings'; -import { metrics } from '../../metrics'; -import { hasPermission, hasAllPermission } from '../../authorization'; +import { Logger } from '../../../server/lib/logger/Logger'; +import { getRestPayload } from '../../../server/lib/logger/logPayloads'; +import { settings } from '../../settings/server'; +import { metrics } from '../../metrics/server'; +import { hasPermission, hasAllPermission } from '../../authorization/server'; import { getDefaultUserFields } from '../../utils/server/functions/getDefaultUserFields'; import { checkCodeForUser } from '../../2fa/server/code'; -const logger = new Logger('API', {}); - -const { - LOG_REST_PAYLOAD = 'false', - LOG_REST_METHOD_PAYLOADS = 'false', -} = process.env; - -const addPayloadToLog = LOG_REST_PAYLOAD !== 'false' || LOG_REST_METHOD_PAYLOADS !== 'false'; +const logger = new Logger('API'); const rateLimiterDictionary = {}; export const defaultRateLimiterOptions = { @@ -134,8 +128,6 @@ export class APIClass extends Restivus { body: result, }; - logger.debug('Success', result); - return result; } @@ -167,8 +159,6 @@ export class APIClass extends Restivus { body: result, }; - logger.debug('Failure', result); - return result; } @@ -359,10 +349,26 @@ export class APIClass extends Restivus { }); this.requestIp = getRequestIP(this.request); + + const startTime = Date.now(); + + const log = logger.logger.child({ + method: this.request.method, + url: this.request.url, + userId: this.request.headers['x-user-id'], + userAgent: this.request.headers['user-agent'], + length: this.request.headers['content-length'], + host: this.request.headers.host, + referer: this.request.headers.referer, + remoteIP: this.requestIp, + ...getRestPayload(this.request.body), + }); + const objectForRateLimitMatch = { IPAddr: this.requestIp, route: `${ this.request.route }${ this.request.method.toLowerCase() }`, }; + let result; const connection = { @@ -397,25 +403,29 @@ export class APIClass extends Restivus { api.processTwoFactor({ userId: this.userId, request: this.request, invocation, options: _options.twoFactorOptions, connection }); } - result = DDP._CurrentInvocation.withValue(invocation, () => originalAction.apply(this)); - } catch (e) { - logger.debug(`${ method } ${ route } threw an error:`, e.stack); + result = DDP._CurrentInvocation.withValue(invocation, () => originalAction.apply(this)) || API.v1.success(); + log.http({ + status: result.statusCode, + responseTime: Date.now() - startTime, + }); + } catch (e) { const apiMethod = { 'error-too-many-requests': 'tooManyRequests', 'error-unauthorized': 'unauthorized', }[e.error] || 'failure'; result = API.v1[apiMethod](typeof e === 'string' ? e : e.message, e.error, process.env.TEST_MODE ? e.stack : undefined, e); + + log.http({ + err: e, + status: result.statusCode, + responseTime: Date.now() - startTime, + }); } finally { delete Accounts._accountData[connection.id]; } - const dateTime = new Date().toISOString(); - logger.info(() => `${ this.requestIp } - ${ this.userId } [${ dateTime }] "${ this.request.method } ${ this.request.url }" ${ result.statusCode } - "${ this.request.headers.referer }" "${ this.request.headers['user-agent'] }" | ${ addPayloadToLog ? JSON.stringify(this.request.body) : '' }`); - - result = result || API.v1.success(); - rocketchatRestApiEnd({ status: result.statusCode, }); diff --git a/app/api/server/v1/misc.js b/app/api/server/v1/misc.js index 01376658e4eb..57f88df0a6b5 100644 --- a/app/api/server/v1/misc.js +++ b/app/api/server/v1/misc.js @@ -15,7 +15,7 @@ import { API } from '../api'; import { getDefaultUserFields } from '../../../utils/server/functions/getDefaultUserFields'; import { getURL } from '../../../utils/lib/getURL'; import { StdOut } from '../../../logger/server/streamer'; -import { SystemLogger } from '../../../logger/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; // DEPRECATED diff --git a/app/apps/server/communication/uikit.js b/app/apps/server/communication/uikit.js index d86aa6b8fb4c..4abc6b992ab3 100644 --- a/app/apps/server/communication/uikit.js +++ b/app/apps/server/communication/uikit.js @@ -263,7 +263,6 @@ const appsRoutes = (orch) => (req, res) => { res.sendStatus(200); } catch (e) { - console.error(e); res.status(500).send(e.message); } break; @@ -297,6 +296,10 @@ const appsRoutes = (orch) => (req, res) => { } break; } + + default: { + res.status(500).send({ error: 'Unknown action' }); + } } // TODO: validate payloads per type diff --git a/app/apps/server/communication/websockets.js b/app/apps/server/communication/websockets.js index fd9360dce473..f5eadf281d97 100644 --- a/app/apps/server/communication/websockets.js +++ b/app/apps/server/communication/websockets.js @@ -1,5 +1,6 @@ import { AppStatusUtils } from '@rocket.chat/apps-engine/definition/AppStatus'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import notifications from '../../../notifications/server/lib/Notifications'; export const AppEvents = Object.freeze({ @@ -49,10 +50,10 @@ export class AppServerListener { this.received.set(`${ AppEvents.APP_STATUS_CHANGE }_${ appId }`, { appId, status, when: new Date() }); if (AppStatusUtils.isEnabled(status)) { - await this.orch.getManager().enable(appId).catch(console.error); + await this.orch.getManager().enable(appId).catch(SystemLogger.error); this.clientStreamer.emitWithoutBroadcast(AppEvents.APP_STATUS_CHANGE, { appId, status }); } else if (AppStatusUtils.isDisabled(status)) { - await this.orch.getManager().disable(appId, status, true).catch(console.error); + await this.orch.getManager().disable(appId, status, true).catch(SystemLogger.error); this.clientStreamer.emitWithoutBroadcast(AppEvents.APP_STATUS_CHANGE, { appId, status }); } } diff --git a/app/authentication/server/lib/logLoginAttempts.ts b/app/authentication/server/lib/logLoginAttempts.ts index 699c7c00ddd0..ed73cf395e6d 100644 --- a/app/authentication/server/lib/logLoginAttempts.ts +++ b/app/authentication/server/lib/logLoginAttempts.ts @@ -1,5 +1,6 @@ import { ILoginAttempt } from '../ILoginAttempt'; import { settings } from '../../../settings/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export const logFailedLoginAttempts = (login: ILoginAttempt): void => { if (!settings.get('Login_Logs_Enabled')) { @@ -25,5 +26,5 @@ export const logFailedLoginAttempts = (login: ILoginAttempt): void => { if (!settings.get('Login_Logs_UserAgent')) { userAgent = '-'; } - console.log('Failed login detected - Username[%s] ClientAddress[%s] ForwardedFor[%s] XRealIp[%s] UserAgent[%s]', user, clientAddress, forwardedFor, realIp, userAgent); + SystemLogger.info(`Failed login detected - Username[${ user }] ClientAddress[${ clientAddress }] ForwardedFor[${ forwardedFor }] XRealIp[${ realIp }] UserAgent[${ userAgent }]`); }; diff --git a/app/authentication/server/lib/restrictLoginAttempts.ts b/app/authentication/server/lib/restrictLoginAttempts.ts index a746d6e7938e..d62f090b1364 100644 --- a/app/authentication/server/lib/restrictLoginAttempts.ts +++ b/app/authentication/server/lib/restrictLoginAttempts.ts @@ -16,7 +16,6 @@ const logger = new Logger('LoginProtection'); export const notifyFailedLogin = async (ipOrUsername: string, blockedUntil: Date, failedAttempts: number): Promise => { const channelToNotify = settings.get('Block_Multiple_Failed_Logins_Notify_Failed_Channel'); if (!channelToNotify) { - /* @ts-expect-error */ logger.error('Cannot notify failed logins: channel provided is invalid'); return; } @@ -24,7 +23,6 @@ export const notifyFailedLogin = async (ipOrUsername: string, blockedUntil: Date // to avoid issues when "fname" is presented in the UI, check if the name matches it as well const room = await Rooms.findOneByNameOrFname(channelToNotify); if (!room) { - /* @ts-expect-error */ logger.error('Cannot notify failed logins: channel provided doesn\'t exists'); return; } diff --git a/app/autotranslate/server/deeplTranslate.js b/app/autotranslate/server/deeplTranslate.js index 91145470cf55..b45500602a3b 100644 --- a/app/autotranslate/server/deeplTranslate.js +++ b/app/autotranslate/server/deeplTranslate.js @@ -7,7 +7,7 @@ import { HTTP } from 'meteor/http'; import _ from 'underscore'; import { TranslationProviderRegistry, AutoTranslate } from './autotranslate'; -import { SystemLogger } from '../../logger/server'; +import { SystemLogger } from '../../../server/lib/logger/system'; import { settings } from '../../settings'; /** diff --git a/app/autotranslate/server/googleTranslate.js b/app/autotranslate/server/googleTranslate.js index b2463718e6f5..88c5403e550b 100644 --- a/app/autotranslate/server/googleTranslate.js +++ b/app/autotranslate/server/googleTranslate.js @@ -7,7 +7,7 @@ import { HTTP } from 'meteor/http'; import _ from 'underscore'; import { AutoTranslate, TranslationProviderRegistry } from './autotranslate'; -import { SystemLogger } from '../../logger/server'; +import { SystemLogger } from '../../../server/lib/logger/system'; import { settings } from '../../settings'; /** diff --git a/app/autotranslate/server/logger.js b/app/autotranslate/server/logger.js index 8f104e75e88c..70ca0cbf97b6 100644 --- a/app/autotranslate/server/logger.js +++ b/app/autotranslate/server/logger.js @@ -1,9 +1,5 @@ -import { Logger } from '../../logger'; +import { Logger } from '../../logger/server'; -export const logger = new Logger('AutoTranslate', { - sections: { - google: 'Google', - deepl: 'DeepL', - microsoft: 'Microsoft', - }, -}); +const logger = new Logger('AutoTranslate'); + +export const msLogger = logger.section('Microsoft'); diff --git a/app/autotranslate/server/msTranslate.js b/app/autotranslate/server/msTranslate.js index a71d450fa72d..1c3da27e6c29 100644 --- a/app/autotranslate/server/msTranslate.js +++ b/app/autotranslate/server/msTranslate.js @@ -7,7 +7,7 @@ import { HTTP } from 'meteor/http'; import _ from 'underscore'; import { TranslationProviderRegistry, AutoTranslate } from './autotranslate'; -import { logger } from './logger'; +import { msLogger } from './logger'; import { settings } from '../../settings'; /** @@ -137,7 +137,7 @@ class MsAutoTranslate extends AutoTranslate { try { return this._translate(msgs, targetLanguages); } catch (e) { - logger.microsoft.error('Error translating message', e); + msLogger.error({ err: e, msg: 'Error translating message' }); } return {}; } @@ -155,7 +155,7 @@ class MsAutoTranslate extends AutoTranslate { Text: attachment.description || attachment.text, }], targetLanguages); } catch (e) { - logger.microsoft.error('Error translating message attachment', e); + msLogger.error({ err: e, msg: 'Error translating message attachment' }); } return {}; } diff --git a/app/bigbluebutton/server/bigbluebutton-api.js b/app/bigbluebutton/server/bigbluebutton-api.js index b90424914736..f1c8c471027f 100644 --- a/app/bigbluebutton/server/bigbluebutton-api.js +++ b/app/bigbluebutton/server/bigbluebutton-api.js @@ -7,15 +7,11 @@ var BigBlueButtonApi, filterCustomParameters, include, noChecksumMethods, BigBlueButtonApi = (function () { function BigBlueButtonApi(url, salt, debug, opts) { var _base; - if (debug == null) { - debug = false; - } if (opts == null) { opts = {}; } this.url = url; this.salt = salt; - this.debug = debug; this.opts = opts; if ((_base = this.opts).shaType == null) { _base.shaType = 'sha1'; @@ -82,9 +78,7 @@ BigBlueButtonApi = (function () { if (filter == null) { filter = true; } - if (this.debug) { - console.log("Generating URL for", method); - } + SystemLogger.debug("Generating URL for", method); if (filter) { params = this.filterParams(params, method); } else { @@ -132,9 +126,7 @@ BigBlueButtonApi = (function () { BigBlueButtonApi.prototype.checksum = function (method, query) { var c, shaObj, str; query || (query = ""); - if (this.debug) { - console.log("- Calculating the checksum using: '" + method + "', '" + query + "', '" + this.salt + "'"); - } + SystemLogger.debug("- Calculating the checksum using: '" + method + "', '" + query + "', '" + this.salt + "'"); str = method + query + this.salt; if (this.opts.shaType === 'sha256') { shaObj = crypto.createHash('sha256', "TEXT") @@ -143,9 +135,7 @@ BigBlueButtonApi = (function () { } shaObj.update(str); c = shaObj.digest('hex'); - if (this.debug) { - console.log("- Checksum calculated:", c); - } + SystemLogger.debug("- Checksum calculated:", c); return c; }; diff --git a/app/blockstack/server/loginHandler.js b/app/blockstack/server/loginHandler.js index de00f0d1ccf4..53756efe8891 100644 --- a/app/blockstack/server/loginHandler.js +++ b/app/blockstack/server/loginHandler.js @@ -44,7 +44,7 @@ Accounts.registerLoginHandler('blockstack', (loginRequest) => { }); } } catch (e) { - console.error(e); + logger.error(e); } } diff --git a/app/callbacks/lib/callbacks.js b/app/callbacks/lib/callbacks.js index 525d869e191b..5def1fcfb9bd 100644 --- a/app/callbacks/lib/callbacks.js +++ b/app/callbacks/lib/callbacks.js @@ -16,7 +16,7 @@ if (Meteor.isClient) { } if (Meteor.isServer) { - const { Logger } = require('../../logger/server/server'); + const { Logger } = require('../../../server/lib/logger/Logger'); logger = new Logger('Callbacks'); } diff --git a/app/cas/server/cas_rocketchat.js b/app/cas/server/cas_rocketchat.js index 47dd4b405e25..6e4fea97c122 100644 --- a/app/cas/server/cas_rocketchat.js +++ b/app/cas/server/cas_rocketchat.js @@ -4,7 +4,7 @@ import { ServiceConfiguration } from 'meteor/service-configuration'; import { Logger } from '../../logger'; import { settings } from '../../settings'; -export const logger = new Logger('CAS', {}); +export const logger = new Logger('CAS'); Meteor.startup(function() { settings.addGroup('CAS', function() { diff --git a/app/chatpal-search/server/provider/index.js b/app/chatpal-search/server/provider/index.js index 4195805d53b7..9a3ad7c56f75 100644 --- a/app/chatpal-search/server/provider/index.js +++ b/app/chatpal-search/server/provider/index.js @@ -29,13 +29,13 @@ class Backend { const response = HTTP.call('POST', `${ this._options.baseurl }${ this._options.updatepath }`, options); if (response.statusCode >= 200 && response.statusCode < 300) { - ChatpalLogger.debug(`indexed ${ docs.length } documents`, JSON.stringify(response.data, null, 2)); + ChatpalLogger.debug({ msg: `indexed ${ docs.length } documents`, data: response.data }); } else { throw new Error(response); } } catch (e) { // TODO how to deal with this - ChatpalLogger.error('indexing failed', JSON.stringify(e, null, 2)); + ChatpalLogger.error({ msg: 'indexing failed', err: e }); return false; } } @@ -83,7 +83,7 @@ class Backend { ...this._options.httpOptions, }; - ChatpalLogger.debug('query: ', JSON.stringify(options, null, 2)); + ChatpalLogger.debug({ query: options }); try { if (callback) { @@ -101,7 +101,7 @@ class Backend { throw new Error(response); } } catch (e) { - ChatpalLogger.error('query failed', JSON.stringify(e, null, 2)); + ChatpalLogger.error({ msg: 'query failed', err: e }); throw e; } } diff --git a/app/chatpal-search/server/provider/provider.js b/app/chatpal-search/server/provider/provider.js index ff8e6fb3bc1c..e60d9c507aff 100644 --- a/app/chatpal-search/server/provider/provider.js +++ b/app/chatpal-search/server/provider/provider.js @@ -286,8 +286,8 @@ class ChatpalProvider extends SearchProvider { this._stats = server.stats; - ChatpalLogger.debug('config:', JSON.stringify(this._indexConfig, null, 2)); - ChatpalLogger.debug('stats:', JSON.stringify(this._stats, null, 2)); + ChatpalLogger.debug({ config: this._indexConfig }); + ChatpalLogger.debug({ stats: this._stats }); this.index = new Index(this._indexConfig, this.indexFail || clear, this._stats.message.oldest || new Date().valueOf()); diff --git a/app/chatpal-search/server/utils/logger.js b/app/chatpal-search/server/utils/logger.js index c1d75b806a2c..bfc73d4ecbc7 100644 --- a/app/chatpal-search/server/utils/logger.js +++ b/app/chatpal-search/server/utils/logger.js @@ -1,4 +1,4 @@ import { Logger } from '../../../logger'; -const ChatpalLogger = new Logger('Chatpal Logger', {}); +const ChatpalLogger = new Logger('Chatpal Logger'); export default ChatpalLogger; diff --git a/app/cloud/server/functions/connectWorkspace.js b/app/cloud/server/functions/connectWorkspace.js index 6e428803dc0c..974eb47d0668 100644 --- a/app/cloud/server/functions/connectWorkspace.js +++ b/app/cloud/server/functions/connectWorkspace.js @@ -6,6 +6,7 @@ import { retrieveRegistrationStatus } from './retrieveRegistrationStatus'; import { Settings } from '../../../models'; import { settings } from '../../../settings'; import { saveRegistrationData } from './saveRegistrationData'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export function connectWorkspace(token) { const { connectToCloud } = retrieveRegistrationStatus(); @@ -38,9 +39,9 @@ export function connectWorkspace(token) { }); } catch (e) { if (e.response && e.response.data && e.response.data.error) { - console.error(`Failed to register with Rocket.Chat Cloud. Error: ${ e.response.data.error }`); + SystemLogger.error(`Failed to register with Rocket.Chat Cloud. Error: ${ e.response.data.error }`); } else { - console.error(e); + SystemLogger.error(e); } return false; diff --git a/app/cloud/server/functions/finishOAuthAuthorization.js b/app/cloud/server/functions/finishOAuthAuthorization.js index 5bf24cb9992b..60691ed20dce 100644 --- a/app/cloud/server/functions/finishOAuthAuthorization.js +++ b/app/cloud/server/functions/finishOAuthAuthorization.js @@ -5,6 +5,7 @@ import { getRedirectUri } from './getRedirectUri'; import { settings } from '../../../settings'; import { Users } from '../../../models'; import { userScopes } from '../oauthScopes'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export function finishOAuthAuthorization(code, state) { if (settings.get('Cloud_Workspace_Registration_State') !== state) { @@ -32,9 +33,9 @@ export function finishOAuthAuthorization(code, state) { }); } catch (e) { if (e.response && e.response.data && e.response.data.error) { - console.error(`Failed to get AccessToken from Rocket.Chat Cloud. Error: ${ e.response.data.error }`); + SystemLogger.error(`Failed to get AccessToken from Rocket.Chat Cloud. Error: ${ e.response.data.error }`); } else { - console.error(e); + SystemLogger.error(e); } return false; diff --git a/app/cloud/server/functions/getUserCloudAccessToken.js b/app/cloud/server/functions/getUserCloudAccessToken.js index 3be0f726b121..f6a48a0ad63e 100644 --- a/app/cloud/server/functions/getUserCloudAccessToken.js +++ b/app/cloud/server/functions/getUserCloudAccessToken.js @@ -8,6 +8,7 @@ import { userLoggedOut } from './userLoggedOut'; import { Users } from '../../../models'; import { settings } from '../../../settings'; import { userScopes } from '../oauthScopes'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export function getUserCloudAccessToken(userId, forceNew = false, scope = '', save = true) { const { connectToCloud, workspaceRegistered } = retrieveRegistrationStatus(); @@ -63,10 +64,10 @@ export function getUserCloudAccessToken(userId, forceNew = false, scope = '', sa }); } catch (e) { if (e.response && e.response.data && e.response.data.error) { - console.error(`Failed to get User AccessToken from Rocket.Chat Cloud. Error: ${ e.response.data.error }`); + SystemLogger.error(`Failed to get User AccessToken from Rocket.Chat Cloud. Error: ${ e.response.data.error }`); if (e.response.data.error === 'oauth_invalid_client_credentials') { - console.error('Server has been unregistered from cloud'); + SystemLogger.error('Server has been unregistered from cloud'); unregisterWorkspace(); } @@ -74,7 +75,7 @@ export function getUserCloudAccessToken(userId, forceNew = false, scope = '', sa userLoggedOut(userId); } } else { - console.error(e); + SystemLogger.error(e); } return ''; diff --git a/app/cloud/server/functions/getWorkspaceAccessTokenWithScope.js b/app/cloud/server/functions/getWorkspaceAccessTokenWithScope.js index f7ad77aa38d1..6acdbe8be039 100644 --- a/app/cloud/server/functions/getWorkspaceAccessTokenWithScope.js +++ b/app/cloud/server/functions/getWorkspaceAccessTokenWithScope.js @@ -6,6 +6,7 @@ import { retrieveRegistrationStatus } from './retrieveRegistrationStatus'; import { unregisterWorkspace } from './unregisterWorkspace'; import { settings } from '../../../settings'; import { workspaceScopes } from '../oauthScopes'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export function getWorkspaceAccessTokenWithScope(scope = '') { const { connectToCloud, workspaceRegistered } = retrieveRegistrationStatus(); @@ -43,14 +44,14 @@ export function getWorkspaceAccessTokenWithScope(scope = '') { }); } catch (e) { if (e.response && e.response.data && e.response.data.error) { - console.error(`Failed to get AccessToken from Rocket.Chat Cloud. Error: ${ e.response.data.error }`); + SystemLogger.error(`Failed to get AccessToken from Rocket.Chat Cloud. Error: ${ e.response.data.error }`); if (e.response.data.error === 'oauth_invalid_client_credentials') { - console.error('Server has been unregistered from cloud'); + SystemLogger.error('Server has been unregistered from cloud'); unregisterWorkspace(); } } else { - console.error(e); + SystemLogger.error(e); } return tokenResponse; diff --git a/app/cloud/server/functions/getWorkspaceLicense.js b/app/cloud/server/functions/getWorkspaceLicense.js index 00916c9b93db..1483e04d3d16 100644 --- a/app/cloud/server/functions/getWorkspaceLicense.js +++ b/app/cloud/server/functions/getWorkspaceLicense.js @@ -5,6 +5,7 @@ import { settings } from '../../../settings'; import { Settings } from '../../../models'; import { callbacks } from '../../../callbacks'; import { LICENSE_VERSION } from '../license'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export function getWorkspaceLicense() { const token = getWorkspaceAccessToken(); @@ -22,9 +23,9 @@ export function getWorkspaceLicense() { }); } catch (e) { if (e.response && e.response.data && e.response.data.error) { - console.error(`Failed to update license from Rocket.Chat Cloud. Error: ${ e.response.data.error }`); + SystemLogger.error(`Failed to update license from Rocket.Chat Cloud. Error: ${ e.response.data.error }`); } else { - console.error(e); + SystemLogger.error(e); } return { updated: false, license: '' }; diff --git a/app/cloud/server/functions/startRegisterWorkspace.js b/app/cloud/server/functions/startRegisterWorkspace.js index 84837dcdaf61..eba17c2649b1 100644 --- a/app/cloud/server/functions/startRegisterWorkspace.js +++ b/app/cloud/server/functions/startRegisterWorkspace.js @@ -5,6 +5,7 @@ import { syncWorkspace } from './syncWorkspace'; import { settings } from '../../../settings'; import { Settings } from '../../../models'; import { buildWorkspaceRegistrationData } from './buildRegistrationData'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export function startRegisterWorkspace(resend = false) { @@ -28,9 +29,9 @@ export function startRegisterWorkspace(resend = false) { }); } catch (e) { if (e.response && e.response.data && e.response.data.error) { - console.error(`Failed to register with Rocket.Chat Cloud. ErrorCode: ${ e.response.data.error }`); + SystemLogger.error(`Failed to register with Rocket.Chat Cloud. ErrorCode: ${ e.response.data.error }`); } else { - console.error(e); + SystemLogger.error(e); } return false; diff --git a/app/cloud/server/functions/syncWorkspace.js b/app/cloud/server/functions/syncWorkspace.js index 360309c7cd5c..03f67acf4a4b 100644 --- a/app/cloud/server/functions/syncWorkspace.js +++ b/app/cloud/server/functions/syncWorkspace.js @@ -8,6 +8,7 @@ import { Settings } from '../../../models'; import { settings } from '../../../settings'; import { getAndCreateNpsSurvey } from '../../../../server/services/nps/getAndCreateNpsSurvey'; import { NPS, Banner } from '../../../../server/sdk'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export function syncWorkspace(reconnectCheck = false) { const { workspaceRegistered, connectToCloud } = retrieveRegistrationStatus(); @@ -38,9 +39,9 @@ export function syncWorkspace(reconnectCheck = false) { getWorkspaceLicense(); } catch (e) { if (e.response && e.response.data && e.response.data.error) { - console.error(`Failed to sync with Rocket.Chat Cloud. Error: ${ e.response.data.error }`); + SystemLogger.error(`Failed to sync with Rocket.Chat Cloud. Error: ${ e.response.data.error }`); } else { - console.error(e); + SystemLogger.error(e); } return false; diff --git a/app/cloud/server/functions/userLogout.js b/app/cloud/server/functions/userLogout.js index 5dea9eb07815..405ab5bd0d73 100644 --- a/app/cloud/server/functions/userLogout.js +++ b/app/cloud/server/functions/userLogout.js @@ -4,6 +4,7 @@ import { userLoggedOut } from './userLoggedOut'; import { retrieveRegistrationStatus } from './retrieveRegistrationStatus'; import { Users } from '../../../models'; import { settings } from '../../../settings'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export function userLogout(userId) { const { connectToCloud, workspaceRegistered } = retrieveRegistrationStatus(); @@ -41,9 +42,9 @@ export function userLogout(userId) { }); } catch (e) { if (e.response && e.response.data && e.response.data.error) { - console.error(`Failed to get Revoke refresh token to logout of Rocket.Chat Cloud. Error: ${ e.response.data.error }`); + SystemLogger.error(`Failed to get Revoke refresh token to logout of Rocket.Chat Cloud. Error: ${ e.response.data.error }`); } else { - console.error(e); + SystemLogger.error(e); } } } diff --git a/app/cors/server/cors.js b/app/cors/server/cors.js index b14d6b5588bb..9033d0b548f8 100644 --- a/app/cors/server/cors.js +++ b/app/cors/server/cors.js @@ -8,7 +8,7 @@ import { settings } from '../../settings'; import { Logger } from '../../logger'; -const logger = new Logger('CORS', {}); +const logger = new Logger('CORS'); // Deprecated setting let Support_Cordova_App = false; diff --git a/app/crowd/server/crowd.js b/app/crowd/server/crowd.js index a4cc46ca45ba..f2dd3acbaee9 100644 --- a/app/crowd/server/crowd.js +++ b/app/crowd/server/crowd.js @@ -11,7 +11,7 @@ import { settings } from '../../settings'; import { hasRole } from '../../authorization'; import { deleteUser } from '../../lib/server/functions'; -const logger = new Logger('CROWD', {}); +const logger = new Logger('CROWD'); function fallbackDefaultAccountSystem(bind, username, password) { if (typeof username === 'string') { diff --git a/app/custom-oauth/server/custom_oauth_server.js b/app/custom-oauth/server/custom_oauth_server.js index bd698fd90c2b..b8b49aafda93 100644 --- a/app/custom-oauth/server/custom_oauth_server.js +++ b/app/custom-oauth/server/custom_oauth_server.js @@ -190,7 +190,7 @@ export class CustomOAuth { data = JSON.parse(response.content); } - logger.debug('Identity response', JSON.stringify(data, null, 2)); + logger.debug({ msg: 'Identity response', data }); return this.normalizeIdentity(data); } catch (err) { diff --git a/app/custom-oauth/server/oauth_helpers.js b/app/custom-oauth/server/oauth_helpers.js index f00eea03b6b7..7520f041eb65 100644 --- a/app/custom-oauth/server/oauth_helpers.js +++ b/app/custom-oauth/server/oauth_helpers.js @@ -3,7 +3,7 @@ import { Roles, Rooms } from '../../models'; import { addUserToRoom, createRoom } from '../../lib/server/functions'; import { Logger } from '../../logger'; -export const logger = new Logger('OAuth', {}); +export const logger = new Logger('OAuth'); // Returns list of roles from SSO identity export function mapRolesFromSSO(identity, roleClaimName) { diff --git a/app/custom-sounds/server/startup/custom-sounds.js b/app/custom-sounds/server/startup/custom-sounds.js index 77a0d2c52b38..00349dfd706d 100644 --- a/app/custom-sounds/server/startup/custom-sounds.js +++ b/app/custom-sounds/server/startup/custom-sounds.js @@ -3,6 +3,7 @@ import { WebApp } from 'meteor/webapp'; import { RocketChatFile } from '../../../file/server'; import { settings } from '../../../settings/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export let RocketChatFileCustomSoundsInstance; @@ -19,7 +20,7 @@ Meteor.startup(function() { throw new Error(`Invalid RocketChatStore type [${ storeType }]`); } - console.log(`Using ${ storeType } for custom sounds storage`.green); + SystemLogger.info(`Using ${ storeType } for custom sounds storage`); let path = '~/uploads'; if (settings.get('CustomSounds_FileSystemPath') != null) { diff --git a/app/emoji-custom/server/startup/emoji-custom.js b/app/emoji-custom/server/startup/emoji-custom.js index 8decb068ea1e..c7a83a0cf301 100644 --- a/app/emoji-custom/server/startup/emoji-custom.js +++ b/app/emoji-custom/server/startup/emoji-custom.js @@ -2,7 +2,8 @@ import { Meteor } from 'meteor/meteor'; import { WebApp } from 'meteor/webapp'; import _ from 'underscore'; -import { settings } from '../../../settings'; +import { settings } from '../../../settings/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { RocketChatFile } from '../../../file'; export let RocketChatFileEmojiCustomInstance; @@ -20,7 +21,7 @@ Meteor.startup(function() { throw new Error(`Invalid RocketChatStore type [${ storeType }]`); } - console.log(`Using ${ storeType } for custom emoji storage`.green); + SystemLogger.info(`Using ${ storeType } for custom emoji storage`); let path = '~/uploads'; if (settings.get('EmojiUpload_FileSystemPath') != null) { diff --git a/app/federation/server/endpoints/dispatch.js b/app/federation/server/endpoints/dispatch.js index d518505127c2..ae392ac8aac8 100644 --- a/app/federation/server/endpoints/dispatch.js +++ b/app/federation/server/endpoints/dispatch.js @@ -1,7 +1,7 @@ import { EJSON } from 'meteor/ejson'; import { API } from '../../../api/server'; -import { logger } from '../lib/logger'; +import { serverLogger } from '../lib/logger'; import { contextDefinitions, eventTypes } from '../../../models/server/models/FederationEvents'; import { FederationRoomEvents, FederationServers, @@ -134,7 +134,7 @@ const eventHandlers = { federationAltered = true; } } catch (ex) { - logger.server.debug(`unable to create subscription for user ( ${ user._id } ) in room (${ roomId })`); + serverLogger.debug(`unable to create subscription for user ( ${ user._id } ) in room (${ roomId })`); } // Refresh the servers list @@ -267,7 +267,7 @@ const eventHandlers = { notifyUsersOnMessage(denormalizedMessage, room); sendAllNotifications(denormalizedMessage, room); } catch (err) { - logger.server.debug(`Error on creating message: ${ message._id }`); + serverLogger.debug(`Error on creating message: ${ message._id }`); } } } @@ -463,7 +463,7 @@ API.v1.addRoute('federation.events.dispatch', { authRequired: false, rateLimiter // Convert from EJSON const { events } = EJSON.fromJSONValue(payload); - logger.server.debug(`federation.events.dispatch => events=${ events.map((e) => JSON.stringify(e, null, 2)) }`); + serverLogger.debug({ msg: 'federation.events.dispatch', events }); // Loop over received events for (const event of events) { @@ -478,14 +478,14 @@ API.v1.addRoute('federation.events.dispatch', { authRequired: false, rateLimiter // If there was an error handling the event, take action if (!eventResult || !eventResult.success) { try { - logger.server.debug(`federation.events.dispatch => Event has missing parents -> event=${ JSON.stringify(event, null, 2) }`); + serverLogger.debug({ msg: 'federation.events.dispatch => Event has missing parents', event }); requestEventsFromLatest(event.origin, getFederationDomain(), contextDefinitions.defineType(event), event.context, eventResult.latestEventIds); // And stop handling the events break; } catch (err) { - logger.server.error(() => `dispatch => event=${ JSON.stringify(event, null, 2) } eventResult=${ JSON.stringify(eventResult, null, 2) } error=${ err.toString() } ${ err.stack }`); + serverLogger.error({ msg: 'dispatch', event, eventResult, err }); throw err; } diff --git a/app/federation/server/endpoints/requestFromLatest.js b/app/federation/server/endpoints/requestFromLatest.js index 87917880229e..cac0168c8c12 100644 --- a/app/federation/server/endpoints/requestFromLatest.js +++ b/app/federation/server/endpoints/requestFromLatest.js @@ -1,7 +1,7 @@ import { EJSON } from 'meteor/ejson'; import { API } from '../../../api/server'; -import { logger } from '../lib/logger'; +import { serverLogger } from '../lib/logger'; import { FederationRoomEvents } from '../../../models/server'; import { decryptIfNeeded } from '../lib/crypt'; import { isFederationEnabled } from '../lib/isFederationEnabled'; @@ -25,7 +25,7 @@ API.v1.addRoute('federation.events.requestFromLatest', { authRequired: false }, const { fromDomain, contextType, contextQuery, latestEventIds } = EJSON.fromJSONValue(payload); - logger.server.debug(`federation.events.requestFromLatest => contextType=${ contextType } contextQuery=${ JSON.stringify(contextQuery, null, 2) } latestEventIds=${ latestEventIds.join(', ') }`); + serverLogger.debug({ msg: 'federation.events.requestFromLatest', contextType, contextQuery, latestEventIds }); let EventsModel; diff --git a/app/federation/server/endpoints/users.js b/app/federation/server/endpoints/users.js index d74cdae83248..7b92b0b5e509 100644 --- a/app/federation/server/endpoints/users.js +++ b/app/federation/server/endpoints/users.js @@ -1,7 +1,7 @@ import { API } from '../../../api/server'; import { Users } from '../../../models/server'; import { normalizers } from '../normalizers'; -import { logger } from '../lib/logger'; +import { serverLogger } from '../lib/logger'; import { isFederationEnabled } from '../lib/isFederationEnabled'; const userFields = { _id: 1, username: 1, type: 1, emails: 1, name: 1 }; @@ -14,7 +14,7 @@ API.v1.addRoute('federation.users.search', { authRequired: false }, { const { username, domain } = this.requestParams(); - logger.server.debug(`federation.users.search => username=${ username } domain=${ domain }`); + serverLogger.debug(`federation.users.search => username=${ username } domain=${ domain }`); const query = { type: 'user', @@ -41,7 +41,7 @@ API.v1.addRoute('federation.users.getByUsername', { authRequired: false }, { const { username } = this.requestParams(); - logger.server.debug(`federation.users.getByUsername => username=${ username }`); + serverLogger.debug(`federation.users.getByUsername => username=${ username }`); const query = { type: 'user', diff --git a/app/federation/server/handler/index.js b/app/federation/server/handler/index.js index 8ccb510194a5..7827ddf063a7 100644 --- a/app/federation/server/handler/index.js +++ b/app/federation/server/handler/index.js @@ -1,7 +1,7 @@ import qs from 'querystring'; import { disabled } from '../functions/errors'; -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { isFederationEnabled } from '../lib/isFederationEnabled'; import { federationRequestToPeer } from '../lib/http'; @@ -10,7 +10,7 @@ export function federationSearchUsers(query) { throw disabled('client.searchUsers'); } - logger.client.debug(() => `searchUsers => query=${ query }`); + clientLogger.debug({ msg: 'searchUsers', query }); const [username, peerDomain] = query.split('@'); @@ -26,7 +26,7 @@ export function getUserByUsername(query) { throw disabled('client.searchUsers'); } - logger.client.debug(() => `getUserByUsername => query=${ query }`); + clientLogger.debug({ msg: 'getUserByUsername', query }); const [username, peerDomain] = query.split('@'); @@ -42,7 +42,7 @@ export function requestEventsFromLatest(domain, fromDomain, contextType, context throw disabled('client.requestEventsFromLatest'); } - logger.client.debug(() => `requestEventsFromLatest => domain=${ domain } contextType=${ contextType } contextQuery=${ JSON.stringify(contextQuery, null, 2) } latestEventIds=${ latestEventIds.join(', ') }`); + clientLogger.debug({ msg: 'requestEventsFromLatest', domain, contextType, contextQuery, latestEventIds }); const uri = '/api/v1/federation.events.requestFromLatest'; @@ -57,7 +57,7 @@ export function dispatchEvents(domains, events) { domains = [...new Set(domains)]; - logger.client.debug(() => `dispatchEvents => domains=${ domains.join(', ') } events=${ events.map((e) => JSON.stringify(e, null, 2)) }`); + clientLogger.debug({ msg: 'dispatchEvents', domains, events }); const uri = '/api/v1/federation.events.dispatch'; diff --git a/app/federation/server/hooks/afterAddedToRoom.js b/app/federation/server/hooks/afterAddedToRoom.js index 1fd359504c5e..02f76297fcfd 100644 --- a/app/federation/server/hooks/afterAddedToRoom.js +++ b/app/federation/server/hooks/afterAddedToRoom.js @@ -1,4 +1,4 @@ -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { getFederatedRoomData, hasExternalDomain, isLocalUser, checkRoomType, checkRoomDomainsLength } from '../functions/helpers'; import { FederationRoomEvents, Subscriptions } from '../../../models/server'; import { normalizers } from '../normalizers'; @@ -16,7 +16,7 @@ async function afterAddedToRoom(involvedUsers, room) { return involvedUsers; } - logger.client.debug(() => `afterAddedToRoom => involvedUsers=${ JSON.stringify(involvedUsers, null, 2) } room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'afterAddedToRoom', involvedUsers, room }); // If there are not federated users on this room, ignore it const { users, subscriptions } = getFederatedRoomData(room); @@ -73,7 +73,7 @@ async function afterAddedToRoom(involvedUsers, room) { // Remove the user subscription from the room Subscriptions.remove({ _id: subscription._id }); - logger.client.error('afterAddedToRoom => Could not add user:', err); + clientLogger.error({ msg: 'afterAddedToRoom => Could not add user:', err }); } return involvedUsers; diff --git a/app/federation/server/hooks/afterCreateDirectRoom.js b/app/federation/server/hooks/afterCreateDirectRoom.js index a0048fcb24a6..ac05794e1c2e 100644 --- a/app/federation/server/hooks/afterCreateDirectRoom.js +++ b/app/federation/server/hooks/afterCreateDirectRoom.js @@ -1,4 +1,4 @@ -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { FederationRoomEvents, Subscriptions } from '../../../models/server'; import { normalizers } from '../normalizers'; import { deleteRoom } from '../../../lib/server/functions'; @@ -7,7 +7,7 @@ import { dispatchEvents } from '../handler'; import { isFullyQualified } from '../functions/helpers'; async function afterCreateDirectRoom(room, extras) { - logger.client.debug(() => `afterCreateDirectRoom => room=${ JSON.stringify(room, null, 2) } extras=${ JSON.stringify(extras, null, 2) }`); + clientLogger.debug({ msg: 'afterCreateDirectRoom', room, extras }); // If the room is federated, ignore if (room.federation) { return room; } @@ -45,7 +45,7 @@ async function afterCreateDirectRoom(room, extras) { } catch (err) { await deleteRoom(room._id); - logger.client.error('afterCreateDirectRoom => Could not create federated room:', err); + clientLogger.error({ msg: 'afterCreateDirectRoom => Could not create federated room:', err }); } return room; diff --git a/app/federation/server/hooks/afterCreateRoom.js b/app/federation/server/hooks/afterCreateRoom.js index a58d40446c17..75dfeeac6575 100644 --- a/app/federation/server/hooks/afterCreateRoom.js +++ b/app/federation/server/hooks/afterCreateRoom.js @@ -1,4 +1,4 @@ -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { FederationRoomEvents, Subscriptions, Users } from '../../../models/server'; import { normalizers } from '../normalizers'; import { deleteRoom } from '../../../lib/server/functions'; @@ -80,13 +80,13 @@ async function afterCreateRoom(roomOwner, room) { throw new Error('Channels cannot be federated'); } - logger.client.debug(() => `afterCreateRoom => roomOwner=${ JSON.stringify(roomOwner, null, 2) } room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'afterCreateRoom', roomOwner, room }); await doAfterCreateRoom(room, users, subscriptions); } catch (err) { deleteRoom(room._id); - logger.client.error('afterCreateRoom => Could not create federated room:', err); + clientLogger.error({ msg: 'afterCreateRoom => Could not create federated room:', err }); } return room; diff --git a/app/federation/server/hooks/afterDeleteMessage.js b/app/federation/server/hooks/afterDeleteMessage.js index 714de63a6e4d..6d070eafbac0 100644 --- a/app/federation/server/hooks/afterDeleteMessage.js +++ b/app/federation/server/hooks/afterDeleteMessage.js @@ -1,5 +1,5 @@ import { FederationRoomEvents, Rooms } from '../../../models/server'; -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { hasExternalDomain } from '../functions/helpers'; import { getFederationDomain } from '../lib/getFederationDomain'; import { dispatchEvent } from '../handler'; @@ -10,7 +10,7 @@ async function afterDeleteMessage(message) { // If there are not federated users on this room, ignore it if (!hasExternalDomain(room)) { return message; } - logger.client.debug(() => `afterDeleteMessage => message=${ JSON.stringify(message, null, 2) } room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'afterDeleteMessage', message, room }); // Create the delete message event const event = await FederationRoomEvents.createDeleteMessageEvent(getFederationDomain(), room._id, message._id); diff --git a/app/federation/server/hooks/afterLeaveRoom.js b/app/federation/server/hooks/afterLeaveRoom.js index 5f1227df0a69..524d2078ae8a 100644 --- a/app/federation/server/hooks/afterLeaveRoom.js +++ b/app/federation/server/hooks/afterLeaveRoom.js @@ -1,6 +1,6 @@ import { FederationRoomEvents } from '../../../models/server'; import { getFederatedRoomData, hasExternalDomain, isLocalUser } from '../functions/helpers'; -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { normalizers } from '../normalizers'; import { getFederationDomain } from '../lib/getFederationDomain'; import { dispatchEvent } from '../handler'; @@ -13,7 +13,7 @@ async function afterLeaveRoom(user, room) { return user; } - logger.client.debug(() => `afterLeaveRoom => user=${ JSON.stringify(user, null, 2) } room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'afterLeaveRoom', user, room }); const { users } = getFederatedRoomData(room); @@ -40,7 +40,7 @@ async function afterLeaveRoom(user, room) { // Dispatch the events dispatchEvent(domainsBeforeLeft, userLeftEvent); } catch (err) { - logger.client.error('afterLeaveRoom => Could not make user leave:', err); + clientLogger.error({ msg: 'afterLeaveRoom => Could not make user leave:', err }); } return user; diff --git a/app/federation/server/hooks/afterMuteUser.js b/app/federation/server/hooks/afterMuteUser.js index 4dba95ee4df7..6a53d204d0a8 100644 --- a/app/federation/server/hooks/afterMuteUser.js +++ b/app/federation/server/hooks/afterMuteUser.js @@ -1,5 +1,5 @@ import { FederationRoomEvents } from '../../../models/server'; -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { normalizers } from '../normalizers'; import { hasExternalDomain } from '../functions/helpers'; import { getFederationDomain } from '../lib/getFederationDomain'; @@ -9,7 +9,7 @@ async function afterMuteUser(involvedUsers, room) { // If there are not federated users on this room, ignore it if (!hasExternalDomain(room)) { return involvedUsers; } - logger.client.debug(() => `afterMuteUser => involvedUsers=${ JSON.stringify(involvedUsers, null, 2) } room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'afterMuteUser', involvedUsers, room }); const { mutedUser } = involvedUsers; diff --git a/app/federation/server/hooks/afterRemoveFromRoom.js b/app/federation/server/hooks/afterRemoveFromRoom.js index c816f251982b..4c7509ec961e 100644 --- a/app/federation/server/hooks/afterRemoveFromRoom.js +++ b/app/federation/server/hooks/afterRemoveFromRoom.js @@ -1,6 +1,6 @@ import { FederationRoomEvents } from '../../../models/server'; import { getFederatedRoomData, hasExternalDomain, isLocalUser } from '../functions/helpers'; -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { normalizers } from '../normalizers'; import { getFederationDomain } from '../lib/getFederationDomain'; import { dispatchEvent } from '../handler'; @@ -15,7 +15,7 @@ async function afterRemoveFromRoom(involvedUsers, room) { return involvedUsers; } - logger.client.debug(() => `afterRemoveFromRoom => involvedUsers=${ JSON.stringify(involvedUsers, null, 2) } room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'afterRemoveFromRoom', involvedUsers, room }); const { users } = getFederatedRoomData(room); @@ -42,7 +42,7 @@ async function afterRemoveFromRoom(involvedUsers, room) { // Dispatch the events dispatchEvent(domainsBeforeRemoval, removeUserEvent); } catch (err) { - logger.client.error('afterRemoveFromRoom => Could not remove user:', err); + clientLogger.error({ msg: 'afterRemoveFromRoom => Could not remove user:', err }); } return involvedUsers; diff --git a/app/federation/server/hooks/afterSaveMessage.js b/app/federation/server/hooks/afterSaveMessage.js index 5f72868a2323..7fdc128977b5 100644 --- a/app/federation/server/hooks/afterSaveMessage.js +++ b/app/federation/server/hooks/afterSaveMessage.js @@ -1,4 +1,4 @@ -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { FederationRoomEvents } from '../../../models/server'; import { normalizers } from '../normalizers'; import { hasExternalDomain } from '../functions/helpers'; @@ -9,7 +9,7 @@ async function afterSaveMessage(message, room) { // If there are not federated users on this room, ignore it if (!hasExternalDomain(room)) { return message; } - logger.client.debug(() => `afterSaveMessage => message=${ JSON.stringify(message, null, 2) } room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'afterSaveMessage', message, room }); let event; diff --git a/app/federation/server/hooks/afterSetReaction.js b/app/federation/server/hooks/afterSetReaction.js index fec108dd91da..ce3d3d726394 100644 --- a/app/federation/server/hooks/afterSetReaction.js +++ b/app/federation/server/hooks/afterSetReaction.js @@ -1,7 +1,5 @@ -import _ from 'underscore'; - import { FederationRoomEvents, Rooms } from '../../../models/server'; -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { hasExternalDomain } from '../functions/helpers'; import { getFederationDomain } from '../lib/getFederationDomain'; import { dispatchEvent } from '../handler'; @@ -12,7 +10,7 @@ async function afterSetReaction(message, { user, reaction }) { // If there are not federated users on this room, ignore it if (!hasExternalDomain(room)) { return message; } - logger.client.debug(() => `afterSetReaction => message=${ JSON.stringify(_.pick(message, '_id', 'msg'), null, 2) } room=${ JSON.stringify(_.pick(room, '_id'), null, 2) } user=${ JSON.stringify(_.pick(user, 'username'), null, 2) } reaction=${ reaction }`); + clientLogger.debug({ msg: 'afterSetReaction', message, room, user, reaction }); // Create the event const event = await FederationRoomEvents.createSetMessageReactionEvent(getFederationDomain(), room._id, message._id, user.username, reaction); diff --git a/app/federation/server/hooks/afterUnmuteUser.js b/app/federation/server/hooks/afterUnmuteUser.js index 3578e08c97d0..e33ff80ac956 100644 --- a/app/federation/server/hooks/afterUnmuteUser.js +++ b/app/federation/server/hooks/afterUnmuteUser.js @@ -1,5 +1,5 @@ import { FederationRoomEvents } from '../../../models/server'; -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { normalizers } from '../normalizers'; import { hasExternalDomain } from '../functions/helpers'; import { getFederationDomain } from '../lib/getFederationDomain'; @@ -9,7 +9,7 @@ async function afterUnmuteUser(involvedUsers, room) { // If there are not federated users on this room, ignore it if (!hasExternalDomain(room)) { return involvedUsers; } - logger.client.debug(() => `afterUnmuteUser => involvedUsers=${ JSON.stringify(involvedUsers, null, 2) } room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'afterUnmuteUser', involvedUsers, room }); const { unmutedUser } = involvedUsers; diff --git a/app/federation/server/hooks/afterUnsetReaction.js b/app/federation/server/hooks/afterUnsetReaction.js index 72c9259822c0..42d34091c80a 100644 --- a/app/federation/server/hooks/afterUnsetReaction.js +++ b/app/federation/server/hooks/afterUnsetReaction.js @@ -1,7 +1,5 @@ -import _ from 'underscore'; - import { FederationRoomEvents, Rooms } from '../../../models/server'; -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { hasExternalDomain } from '../functions/helpers'; import { getFederationDomain } from '../lib/getFederationDomain'; import { dispatchEvent } from '../handler'; @@ -12,7 +10,7 @@ async function afterUnsetReaction(message, { user, reaction }) { // If there are not federated users on this room, ignore it if (!hasExternalDomain(room)) { return message; } - logger.client.debug(() => `afterUnsetReaction => message=${ JSON.stringify(_.pick(message, '_id', 'msg'), null, 2) } room=${ JSON.stringify(_.pick(room, '_id'), null, 2) } user=${ JSON.stringify(_.pick(user, 'username'), null, 2) } reaction=${ reaction }`); + clientLogger.debug({ msg: 'afterUnsetReaction', message, room, user, reaction }); // Create the event const event = await FederationRoomEvents.createUnsetMessageReactionEvent(getFederationDomain(), room._id, message._id, user.username, reaction); diff --git a/app/federation/server/hooks/beforeDeleteRoom.js b/app/federation/server/hooks/beforeDeleteRoom.js index 0131e4692806..7e55887263df 100644 --- a/app/federation/server/hooks/beforeDeleteRoom.js +++ b/app/federation/server/hooks/beforeDeleteRoom.js @@ -1,4 +1,4 @@ -import { logger } from '../lib/logger'; +import { clientLogger } from '../lib/logger'; import { FederationRoomEvents, Rooms } from '../../../models/server'; import { hasExternalDomain } from '../functions/helpers'; import { getFederationDomain } from '../lib/getFederationDomain'; @@ -13,7 +13,7 @@ async function beforeDeleteRoom(roomId) { // If there are not federated users on this room, ignore it if (!hasExternalDomain(room)) { return roomId; } - logger.client.debug(() => `beforeDeleteRoom => room=${ JSON.stringify(room, null, 2) }`); + clientLogger.debug({ msg: 'beforeDeleteRoom', room }); try { // Create the message event @@ -22,7 +22,7 @@ async function beforeDeleteRoom(roomId) { // Dispatch event (async) dispatchEvent(room.federation.domains, event); } catch (err) { - logger.client.error('beforeDeleteRoom => Could not remove room:', err); + clientLogger.error({ msg: 'beforeDeleteRoom => Could not remove room:', err }); throw err; } diff --git a/app/federation/server/lib/crypt.js b/app/federation/server/lib/crypt.js index ce92cfd84059..7a231a13fb91 100644 --- a/app/federation/server/lib/crypt.js +++ b/app/federation/server/lib/crypt.js @@ -1,7 +1,7 @@ import { FederationKeys } from '../../../models/server'; import { getFederationDomain } from './getFederationDomain'; import { search } from './dns'; -import { logger } from './logger'; +import { cryptLogger } from './logger'; export function decrypt(data, peerKey) { // @@ -15,7 +15,7 @@ export function decrypt(data, peerKey) { // Decrypt with the local private key data = FederationKeys.getPrivateKey().decrypt(data); } catch (err) { - logger.crypt.error(err); + cryptLogger.error(err); throw new Error('Could not decrypt'); } @@ -60,7 +60,7 @@ export function encrypt(data, peerKey) { // Encrypt with the local private key return FederationKeys.getPrivateKey().encryptPrivate(data); } catch (err) { - logger.crypt.error(err); + cryptLogger.error(err); throw new Error('Could not encrypt'); } diff --git a/app/federation/server/lib/dns.js b/app/federation/server/lib/dns.js index 189b8fc18692..0c4e2f348e1b 100644 --- a/app/federation/server/lib/dns.js +++ b/app/federation/server/lib/dns.js @@ -4,7 +4,7 @@ import { Meteor } from 'meteor/meteor'; import mem from 'mem'; import * as federationErrors from '../functions/errors'; -import { logger } from './logger'; +import { dnsLogger } from './logger'; import { isFederationEnabled } from './isFederationEnabled'; import { federationRequest } from './http'; @@ -26,7 +26,7 @@ export function registerWithHub(peerDomain, url, publicKey) { return true; } catch (err) { - logger.dns.error(err); + dnsLogger.error(err); throw federationErrors.peerCouldNotBeRegisteredWithHub('dns.registerWithHub'); } @@ -34,19 +34,19 @@ export function registerWithHub(peerDomain, url, publicKey) { export function searchHub(peerDomain) { try { - logger.dns.debug(`searchHub: peerDomain=${ peerDomain }`); + dnsLogger.debug(`searchHub: peerDomain=${ peerDomain }`); // If there is no DNS entry for that, get from the Hub const { data: { peer } } = federationRequest('GET', `${ hubUrl }/api/v1/peers?search=${ peerDomain }`); if (!peer) { - logger.dns.debug(`searchHub: could not find peerDomain=${ peerDomain }`); + dnsLogger.debug(`searchHub: could not find peerDomain=${ peerDomain }`); throw federationErrors.peerCouldNotBeRegisteredWithHub('dns.registerWithHub'); } const { url, public_key: publicKey } = peer; - logger.dns.debug(`searchHub: found peerDomain=${ peerDomain } url=${ url }`); + dnsLogger.debug(`searchHub: found peerDomain=${ peerDomain } url=${ url }`); return { url, @@ -54,7 +54,7 @@ export function searchHub(peerDomain) { publicKey, }; } catch (err) { - logger.dns.error(err); + dnsLogger.error(err); throw federationErrors.peerNotFoundUsingDNS('dns.searchHub'); } @@ -65,14 +65,14 @@ export function search(peerDomain) { throw federationErrors.disabled('dns.search'); } - logger.dns.debug(`search: peerDomain=${ peerDomain }`); + dnsLogger.debug(`search: peerDomain=${ peerDomain }`); let srvEntries = []; let protocol = ''; // Search by HTTPS first try { - logger.dns.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._https.${ peerDomain }`); + dnsLogger.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._https.${ peerDomain }`); srvEntries = memoizedDnsResolveSRV(`_rocketchat._https.${ peerDomain }`); protocol = 'https'; } catch (err) { @@ -82,7 +82,7 @@ export function search(peerDomain) { // If there is not entry, try with http if (!srvEntries.length) { try { - logger.dns.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._http.${ peerDomain }`); + dnsLogger.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._http.${ peerDomain }`); srvEntries = memoizedDnsResolveSRV(`_rocketchat._http.${ peerDomain }`); protocol = 'http'; } catch (err) { @@ -93,12 +93,12 @@ export function search(peerDomain) { // If there is not entry, try with tcp if (!srvEntries.length) { try { - logger.dns.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._tcp.${ peerDomain }`); + dnsLogger.debug(`search: peerDomain=${ peerDomain } srv=_rocketchat._tcp.${ peerDomain }`); srvEntries = memoizedDnsResolveSRV(`_rocketchat._tcp.${ peerDomain }`); protocol = 'https'; // https is the default // Then, also try to get the protocol - logger.dns.debug(`search: peerDomain=${ peerDomain } txt=rocketchat-tcp-protocol.${ peerDomain }`); + dnsLogger.debug(`search: peerDomain=${ peerDomain } txt=rocketchat-tcp-protocol.${ peerDomain }`); protocol = memoizedDnsResolveSRV(`rocketchat-tcp-protocol.${ peerDomain }`); protocol = protocol[0].join(''); @@ -115,7 +115,7 @@ export function search(peerDomain) { // If there is no entry, throw error if (!srvEntry || !protocol) { - logger.dns.debug(`search: could not find valid SRV entry peerDomain=${ peerDomain } srvEntry=${ JSON.stringify(srvEntry) } protocol=${ protocol }`); + dnsLogger.debug({ msg: 'search: could not find valid SRV entry', peerDomain, srvEntry, protocol }); return searchHub(peerDomain); } @@ -123,7 +123,7 @@ export function search(peerDomain) { // Get the public key from the TXT record try { - logger.dns.debug(`search: peerDomain=${ peerDomain } txt=rocketchat-public-key.${ peerDomain }`); + dnsLogger.debug(`search: peerDomain=${ peerDomain } txt=rocketchat-public-key.${ peerDomain }`); const publicKeyTxtRecords = memoizedDnsResolveTXT(`rocketchat-public-key.${ peerDomain }`); // Join the TXT record, that might be split @@ -134,11 +134,11 @@ export function search(peerDomain) { // If there is no entry, throw error if (!publicKey) { - logger.dns.debug(`search: could not find TXT entry for peerDomain=${ peerDomain } - SRV entry found`); + dnsLogger.debug(`search: could not find TXT entry for peerDomain=${ peerDomain } - SRV entry found`); return searchHub(peerDomain); } - logger.dns.debug(`search: found peerDomain=${ peerDomain } srvEntry=${ srvEntry.name }:${ srvEntry.port } protocol=${ protocol }`); + dnsLogger.debug({ msg: 'search: found', peerDomain, srvEntry, protocol }); return { url: `${ protocol }://${ srvEntry.name }:${ srvEntry.port }`, diff --git a/app/federation/server/lib/http.js b/app/federation/server/lib/http.js index 52cb31480163..542a2d32ef9e 100644 --- a/app/federation/server/lib/http.js +++ b/app/federation/server/lib/http.js @@ -1,7 +1,7 @@ import { HTTP as MeteorHTTP } from 'meteor/http'; import { EJSON } from 'meteor/ejson'; -import { logger } from './logger'; +import { httpLogger } from './logger'; import { getFederationDomain } from './getFederationDomain'; import { search } from './dns'; import { encrypt } from './crypt'; @@ -17,7 +17,7 @@ export function federationRequest(method, url, body, headers, peerKey = null) { } } - logger.http.debug(`[${ method }] ${ url }`); + httpLogger.debug(`[${ method }] ${ url }`); return MeteorHTTP.call(method, url, { data, timeout: 2000, headers: { ...headers, 'x-federation-domain': getFederationDomain() } }); } @@ -37,11 +37,11 @@ export function federationRequestToPeer(method, peerDomain, uri, body, options = let result; try { - logger.http.debug(() => `federationRequestToPeer => url=${ baseUrl }${ uri }`); + httpLogger.debug({ msg: 'federationRequestToPeer', url: `${ baseUrl }${ uri }` }); result = federationRequest(method, `${ baseUrl }${ uri }`, body, options.headers || {}, peerKey); } catch (err) { - logger.http.error(`${ ignoreErrors ? '[IGNORED] ' : '' }Error ${ err }`); + httpLogger.error({ msg: `${ ignoreErrors ? '[IGNORED] ' : '' }Error`, err }); if (!ignoreErrors) { throw err; diff --git a/app/federation/server/lib/logger.js b/app/federation/server/lib/logger.js index f3e791a14bf8..9e66d33808b0 100644 --- a/app/federation/server/lib/logger.js +++ b/app/federation/server/lib/logger.js @@ -1,12 +1,10 @@ import { Logger } from '../../../logger/server'; -export const logger = new Logger('Federation', { - sections: { - client: 'client', - crypt: 'crypt', - dns: 'dns', - http: 'http', - server: 'server', - setup: 'Setup', - }, -}); +const logger = new Logger('Federation'); + +export const clientLogger = logger.section('client'); +export const cryptLogger = logger.section('crypt'); +export const dnsLogger = logger.section('dns'); +export const httpLogger = logger.section('http'); +export const serverLogger = logger.section('server'); +export const setupLogger = logger.section('Setup'); diff --git a/app/federation/server/startup/settings.js b/app/federation/server/startup/settings.js index 48213be78807..a94caaaeff25 100644 --- a/app/federation/server/startup/settings.js +++ b/app/federation/server/startup/settings.js @@ -7,7 +7,7 @@ import { getFederationDomain } from '../lib/getFederationDomain'; import { getFederationDiscoveryMethod } from '../lib/getFederationDiscoveryMethod'; import { registerWithHub } from '../lib/dns'; import { enableCallbacks, disableCallbacks } from '../lib/callbacks'; -import { logger } from '../lib/logger'; +import { setupLogger } from '../lib/logger'; import { FederationKeys } from '../../../models/server'; import { STATUS_ENABLED, STATUS_REGISTERING, STATUS_ERROR_REGISTERING, STATUS_DISABLED } from '../constants'; @@ -89,7 +89,7 @@ const updateSettings = debounce(Meteor.bindEnvironment(function() { }), 150); function enableOrDisable(key, value) { - logger.setup.info(`Federation is ${ value ? 'enabled' : 'disabled' }`); + setupLogger.info(`Federation is ${ value ? 'enabled' : 'disabled' }`); if (value) { updateSettings(); diff --git a/app/file-upload/server/config/AmazonS3.js b/app/file-upload/server/config/AmazonS3.js index fbbb3724ce1a..efbef8d05651 100644 --- a/app/file-upload/server/config/AmazonS3.js +++ b/app/file-upload/server/config/AmazonS3.js @@ -6,13 +6,14 @@ import _ from 'underscore'; import { settings } from '../../../settings'; import { FileUploadClass, FileUpload } from '../lib/FileUpload'; import '../../ufs/AmazonS3/server.js'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const get = function(file, req, res) { const forceDownload = typeof req.query.download !== 'undefined'; this.store.getRedirectURL(file, forceDownload, (err, fileUrl) => { if (err) { - return console.error(err); + return SystemLogger.error(err); } if (!fileUrl) { diff --git a/app/file-upload/server/config/GoogleStorage.js b/app/file-upload/server/config/GoogleStorage.js index c8e11bfe1fb5..1717f38c4240 100644 --- a/app/file-upload/server/config/GoogleStorage.js +++ b/app/file-upload/server/config/GoogleStorage.js @@ -6,13 +6,14 @@ import _ from 'underscore'; import { FileUploadClass, FileUpload } from '../lib/FileUpload'; import { settings } from '../../../settings'; import '../../ufs/GoogleStorage/server.js'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const get = function(file, req, res) { const forceDownload = typeof req.query.download !== 'undefined'; this.store.getRedirectURL(file, forceDownload, (err, fileUrl) => { if (err) { - return console.error(err); + return SystemLogger.error(err); } if (!fileUrl) { @@ -33,7 +34,7 @@ const get = function(file, req, res) { const copy = function(file, out) { this.store.getRedirectURL(file, false, (err, fileUrl) => { if (err) { - console.error(err); + SystemLogger.error(err); } if (fileUrl) { diff --git a/app/file-upload/server/config/Webdav.js b/app/file-upload/server/config/Webdav.js index 8c5382b6b77e..2386b40ae141 100644 --- a/app/file-upload/server/config/Webdav.js +++ b/app/file-upload/server/config/Webdav.js @@ -3,11 +3,12 @@ import _ from 'underscore'; import { FileUploadClass, FileUpload } from '../lib/FileUpload'; import { settings } from '../../../settings'; import '../../ufs/Webdav/server.js'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const get = function(file, req, res) { this.store.getReadStream(file._id, file) .on('error', () => { - console.error('An error ocurred when fetching the file'); + SystemLogger.error('An error ocurred when fetching the file'); res.writeHead(503); res.end(); }) diff --git a/app/file-upload/server/config/_configUploadStorage.js b/app/file-upload/server/config/_configUploadStorage.js index 3fb54925db71..b0b656b5c468 100644 --- a/app/file-upload/server/config/_configUploadStorage.js +++ b/app/file-upload/server/config/_configUploadStorage.js @@ -1,7 +1,8 @@ import { UploadFS } from 'meteor/jalik:ufs'; import _ from 'underscore'; -import { settings } from '../../../settings'; +import { settings } from '../../../settings/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import './AmazonS3.js'; import './FileSystem.js'; import './GoogleStorage.js'; @@ -12,7 +13,7 @@ const configStore = _.debounce(() => { const store = settings.get('FileUpload_Storage_Type'); if (store) { - console.log('Setting default file store to', store); + SystemLogger.info(`Setting default file store to ${ store }`); UploadFS.getStores().Avatars = UploadFS.getStore(`${ store }:Avatars`); UploadFS.getStores().Uploads = UploadFS.getStore(`${ store }:Uploads`); UploadFS.getStores().UserDataFiles = UploadFS.getStore(`${ store }:UserDataFiles`); diff --git a/app/file-upload/server/lib/FileUpload.js b/app/file-upload/server/lib/FileUpload.js index cc9fd2c9a6c3..22e1cfc210fb 100644 --- a/app/file-upload/server/lib/FileUpload.js +++ b/app/file-upload/server/lib/FileUpload.js @@ -28,6 +28,7 @@ import { isValidJWT, generateJWT } from '../../../utils/server/lib/JWTHelper'; import { Messages } from '../../../models/server'; import { AppEvents, Apps } from '../../../apps/server'; import { streamToBuffer } from './streamToBuffer'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const cookie = new Cookies(); let maxFileSize = 0; @@ -235,7 +236,7 @@ export const FileUpload = { .then(Meteor.bindEnvironment(({ data, info }) => { fs.writeFile(tempFilePath, data, Meteor.bindEnvironment((err) => { if (err != null) { - console.error(err); + SystemLogger.error(err); } this.getCollection().direct.update({ _id: file._id }, { @@ -317,7 +318,7 @@ export const FileUpload = { const s = sharp(tmpFile); s.metadata(Meteor.bindEnvironment((err, metadata) => { if (err != null) { - console.error(err); + SystemLogger.error(err); return fut.return(); } @@ -344,7 +345,7 @@ export const FileUpload = { })); })); })).catch((err) => { - console.error(err); + SystemLogger.error(err); fut.return(); }); }; @@ -431,7 +432,7 @@ export const FileUpload = { getStoreByName(handlerName) { if (this.handlers[handlerName] == null) { - console.error(`Upload handler "${ handlerName }" does not exists`); + SystemLogger.error(`Upload handler "${ handlerName }" does not exists`); } return this.handlers[handlerName]; }, diff --git a/app/file-upload/server/lib/proxy.js b/app/file-upload/server/lib/proxy.js index 0921956d111a..2435df950b6d 100644 --- a/app/file-upload/server/lib/proxy.js +++ b/app/file-upload/server/lib/proxy.js @@ -19,7 +19,7 @@ WebApp.connectHandlers.stack.unshift({ return next(); } - logger.debug('Upload URL:', req.url); + logger.debug({ msg: 'Upload URL:', url: req.url }); if (req.method !== 'POST') { return next(); @@ -75,7 +75,7 @@ WebApp.connectHandlers.stack.unshift({ instance.extraInformation.host = 'localhost'; } - logger.debug('Wrong instance, proxing to:', `${ instance.extraInformation.host }:${ instance.extraInformation.port }`); + logger.debug(`Wrong instance, proxing to ${ instance.extraInformation.host }:${ instance.extraInformation.port }`); const options = { hostname: instance.extraInformation.host, @@ -84,7 +84,7 @@ WebApp.connectHandlers.stack.unshift({ method: 'POST', }; - console.warn('UFS proxy middleware is deprecated as this upload method is not being used by Web/Mobile Clients. See this: https://docs.rocket.chat/api/rest-api/methods/rooms/upload'); + logger.warn('UFS proxy middleware is deprecated as this upload method is not being used by Web/Mobile Clients. See this: https://docs.rocket.chat/api/rest-api/methods/rooms/upload'); const proxy = http.request(options, function(proxy_res) { proxy_res.pipe(res, { end: true, diff --git a/app/file-upload/server/methods/sendFileMessage.ts b/app/file-upload/server/methods/sendFileMessage.ts index 6dfeebd29e51..80dec7bca683 100644 --- a/app/file-upload/server/methods/sendFileMessage.ts +++ b/app/file-upload/server/methods/sendFileMessage.ts @@ -11,6 +11,7 @@ import { canAccessRoom } from '../../../authorization/server/functions/canAccess import { MessageAttachment } from '../../../../definition/IMessage/MessageAttachment/MessageAttachment'; import { FileAttachmentProps } from '../../../../definition/IMessage/MessageAttachment/Files/FileAttachmentProps'; import { IUser } from '../../../../definition/IUser'; +import { SystemLogger } from '../../../../server/lib/logger/system'; Meteor.methods({ async sendFileMessage(roomId, _store, file, msgData = {}) { @@ -82,7 +83,7 @@ Meteor.methods({ }); } } catch (e) { - console.error(e); + SystemLogger.error(e); } attachments.push(attachment); } else if (/^audio\/.+/.test(file.type)) { diff --git a/app/file-upload/ufs/AmazonS3/server.js b/app/file-upload/ufs/AmazonS3/server.js index fc6ab49ebd27..e5fb5f87709f 100644 --- a/app/file-upload/ufs/AmazonS3/server.js +++ b/app/file-upload/ufs/AmazonS3/server.js @@ -6,6 +6,8 @@ import { Random } from 'meteor/random'; import _ from 'underscore'; import S3 from 'aws-sdk/clients/s3'; +import { SystemLogger } from '../../../../server/lib/logger/system'; + /** * AmazonS3 store * @param options @@ -91,7 +93,7 @@ export class AmazonS3Store extends UploadFS.Store { s3.deleteObject(params, (err, data) => { if (err) { - console.error(err); + SystemLogger.error(err); } callback && callback(err, data); @@ -144,7 +146,7 @@ export class AmazonS3Store extends UploadFS.Store { }, (error) => { if (error) { - console.error(error); + SystemLogger.error(error); } writeStream.emit('real_finish'); diff --git a/app/file-upload/ufs/GoogleStorage/server.js b/app/file-upload/ufs/GoogleStorage/server.js index 47b384466549..f0fe78265ef7 100644 --- a/app/file-upload/ufs/GoogleStorage/server.js +++ b/app/file-upload/ufs/GoogleStorage/server.js @@ -3,6 +3,8 @@ import { UploadFS } from 'meteor/jalik:ufs'; import { Random } from 'meteor/random'; import { Storage } from '@google-cloud/storage'; +import { SystemLogger } from '../../../../server/lib/logger/system'; + /** * GoogleStorage store * @param options @@ -70,7 +72,7 @@ export class GoogleStorageStore extends UploadFS.Store { const file = this.getCollection().findOne({ _id: fileId }); this.bucket.file(this.getPath(file)).delete(function(err, data) { if (err) { - console.error(err); + SystemLogger.error(err); } callback && callback(err, data); diff --git a/app/file-upload/ufs/Webdav/server.js b/app/file-upload/ufs/Webdav/server.js index 59567fdb4645..3d5326e1f194 100644 --- a/app/file-upload/ufs/Webdav/server.js +++ b/app/file-upload/ufs/Webdav/server.js @@ -5,6 +5,7 @@ import { UploadFS } from 'meteor/jalik:ufs'; import { Random } from 'meteor/random'; import { WebdavClientAdapter } from '../../../webdav/server/lib/webdavClientAdapter'; +import { SystemLogger } from '../../../../server/lib/logger/system'; /** * WebDAV store * @param options @@ -72,7 +73,7 @@ export class WebdavStore extends UploadFS.Store { const file = this.getCollection().findOne({ _id: fileId }); client.deleteFile(this.getPath(file)).then((data) => { callback && callback(null, data); - }).catch(console.error); + }).catch(SystemLogger.error); }; /** diff --git a/app/google-vision/server/googlevision.js b/app/google-vision/server/googlevision.js index 69729c6c1ddb..5179af56587f 100644 --- a/app/google-vision/server/googlevision.js +++ b/app/google-vision/server/googlevision.js @@ -6,6 +6,7 @@ import { callbacks } from '../../callbacks'; import { Uploads, Settings, Users, Messages } from '../../models'; import { FileUpload } from '../../file-upload'; import { api } from '../../../server/sdk/api'; +import { SystemLogger } from '../../../server/lib/logger/system'; class GoogleVision { constructor() { @@ -73,7 +74,7 @@ class GoogleVision { throw new Meteor.Error('GoogleVisionError: Image blocked'); } } else { - console.error('Google Vision: Usage limit exceeded'); + SystemLogger.error('Google Vision: Usage limit exceeded'); } return message; } @@ -116,11 +117,11 @@ class GoogleVision { if (!error) { Messages.setGoogleVisionData(message._id, this.getAnnotations(visionTypes, results)); } else { - console.trace('GoogleVision error: ', error.stack); + SystemLogger.error('GoogleVision error: ', error.stack); } })); } else { - console.error('Google Vision: Usage limit exceeded'); + SystemLogger.error('Google Vision: Usage limit exceeded'); } } } diff --git a/app/iframe-login/server/iframe_server.js b/app/iframe-login/server/iframe_server.js index 586bc8ee8558..95fd1d4cd50f 100644 --- a/app/iframe-login/server/iframe_server.js +++ b/app/iframe-login/server/iframe_server.js @@ -10,8 +10,6 @@ Accounts.registerLoginHandler('iframe', function(result) { check(result.token, String); - console.log('[Method] registerLoginHandler'); - const user = Meteor.users.findOne({ 'services.iframe.token': result.token, }); diff --git a/app/importer-csv/server/importer.js b/app/importer-csv/server/importer.js index 66cc086c1c1a..285f747e6193 100644 --- a/app/importer-csv/server/importer.js +++ b/app/importer-csv/server/importer.js @@ -35,7 +35,7 @@ export class CsvImporter extends Base { oldRate = rate; } } catch (e) { - console.error(e); + this.logger.error(e); } }; diff --git a/app/importer-hipchat-enterprise/server/importer.js b/app/importer-hipchat-enterprise/server/importer.js index 3f59b669e632..b5b2fc2e43b7 100644 --- a/app/importer-hipchat-enterprise/server/importer.js +++ b/app/importer-hipchat-enterprise/server/importer.js @@ -43,7 +43,7 @@ export class HipChatEnterpriseImporter extends Base { this.logger.debug('parsing file contents'); return JSON.parse(dataString); } catch (e) { - console.error(e); + this.logger.error(e); return false; } } diff --git a/app/importer-pending-avatars/server/importer.js b/app/importer-pending-avatars/server/importer.js index 7a8767ba582a..aa12266decf2 100644 --- a/app/importer-pending-avatars/server/importer.js +++ b/app/importer-pending-avatars/server/importer.js @@ -52,7 +52,6 @@ export class PendingAvatarImporter extends Base { Users.update({ _id }, { $unset: { _pendingAvatarUrl: '' } }); } catch (error) { this.logger.warn(`Failed to set ${ name }'s avatar from url ${ url }`); - console.log(`Failed to set ${ name }'s avatar from url ${ url }`); } }); } finally { @@ -65,7 +64,7 @@ export class PendingAvatarImporter extends Base { } catch (error) { // If the cursor expired, restart the method if (error && error.codeName === 'CursorNotFound') { - console.log('CursorNotFound'); + this.logger.info('CursorNotFound'); return this.startImport(); } diff --git a/app/importer-slack/server/importer.js b/app/importer-slack/server/importer.js index 7853b6d54e59..c913c77cbb1d 100644 --- a/app/importer-slack/server/importer.js +++ b/app/importer-slack/server/importer.js @@ -18,7 +18,7 @@ export class SlackImporter extends Base { this.logger.debug('parsing file contents'); return JSON.parse(dataString); } catch (e) { - console.error(e); + this.logger.error(e); return false; } } @@ -197,7 +197,7 @@ export class SlackImporter extends Base { oldRate = rate; } } catch (e) { - console.error(e); + this.logger.error(e); } }; @@ -290,7 +290,7 @@ export class SlackImporter extends Base { }); if (!_.isEmpty(missedTypes)) { - console.log('Missed import types:', missedTypes); + this.logger.info('Missed import types:', missedTypes); } } catch (e) { this.logger.error(e); diff --git a/app/importer/server/classes/ImporterBase.js b/app/importer/server/classes/ImporterBase.js index decfd093543f..75120f6965b9 100644 --- a/app/importer/server/classes/ImporterBase.js +++ b/app/importer/server/classes/ImporterBase.js @@ -54,7 +54,7 @@ export class Base { this.info = info; - this.logger = new Logger(`${ this.info.name } Importer`, {}); + this.logger = new Logger(`${ this.info.name } Importer`); this.converter.setLogger(this.logger); this.progress = new Progress(this.info.key, this.info.name); diff --git a/app/importer/server/startup/setImportsToInvalid.js b/app/importer/server/startup/setImportsToInvalid.js index a7ec86373222..431d4040ab79 100644 --- a/app/importer/server/startup/setImportsToInvalid.js +++ b/app/importer/server/startup/setImportsToInvalid.js @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; -import { Imports } from '../../../models'; +import { Imports } from '../../../models/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { RawImports } from '../models/RawImports'; import { ProgressStep } from '../../lib/ImporterProgressStep'; @@ -8,7 +9,7 @@ function runDrop(fn) { try { fn(); } catch (e) { - console.log('error', e); // TODO: Remove + SystemLogger.error('error', e); // TODO: Remove // ignored } } diff --git a/app/integrations/server/api/api.js b/app/integrations/server/api/api.js index 63d32c9be338..b1d1277b4f3d 100644 --- a/app/integrations/server/api/api.js +++ b/app/integrations/server/api/api.js @@ -10,7 +10,7 @@ import _ from 'underscore'; import s from 'underscore.string'; import moment from 'moment'; -import { logger } from '../logger'; +import { incomingLogger } from '../logger'; import { processWebhookMessage } from '../../../lib'; import { API, APIClass, defaultRateLimiterOptions } from '../../../api/server'; import * as Models from '../../../models'; @@ -63,8 +63,8 @@ function getIntegrationScript(integration) { const script = integration.scriptCompiled; const { sandbox, store } = buildSandbox(); try { - logger.incoming.info('Will evaluate script of Trigger', integration.name); - logger.incoming.debug(script); + incomingLogger.info({ msg: 'Will evaluate script of Trigger', name: integration.name }); + incomingLogger.debug(script); const vmScript = vm.createScript(script, 'script.js'); vmScript.runInNewContext(sandbox); @@ -77,23 +77,20 @@ function getIntegrationScript(integration) { return compiledScripts[integration._id].script; } - } catch ({ stack }) { - logger.incoming.error('[Error evaluating Script in Trigger', integration.name, ':]'); - logger.incoming.error(script.replace(/^/gm, ' ')); - logger.incoming.error('[Stack:]'); - logger.incoming.error(stack.replace(/^/gm, ' ')); + } catch (err) { + incomingLogger.error({ msg: 'Error evaluating Script in Trigger', name: integration.name, script, err }); throw API.v1.failure('error-evaluating-script'); } if (!sandbox.Script) { - logger.incoming.error('[Class "Script" not in Trigger', integration.name, ']'); + incomingLogger.error({ msg: 'Class "Script" not in Trigger', name: integration.name }); throw API.v1.failure('class-script-not-found'); } } function createIntegration(options, user) { - logger.incoming.info('Add integration', options.name); - logger.incoming.debug(options); + incomingLogger.info({ msg: 'Add integration', name: options.name }); + incomingLogger.debug(options); Meteor.runAsUser(user._id, function() { switch (options.event) { @@ -129,8 +126,8 @@ function createIntegration(options, user) { } function removeIntegration(options, user) { - logger.incoming.info('Remove integration'); - logger.incoming.debug(options); + incomingLogger.info('Remove integration'); + incomingLogger.debug(options); const integrationToRemove = Models.Integrations.findOne({ urls: options.target_url, @@ -142,9 +139,8 @@ function removeIntegration(options, user) { } function executeIntegrationRest() { - logger.incoming.info('Post integration:', this.integration.name); - logger.incoming.debug('@urlParams:', this.urlParams); - logger.incoming.debug('@bodyParams:', this.bodyParams); + incomingLogger.info({ msg: 'Post integration:', name: this.integration.name }); + incomingLogger.debug({ urlParams: this.urlParams, bodyParams: this.bodyParams }); if (this.integration.enabled !== true) { return { @@ -165,7 +161,7 @@ function executeIntegrationRest() { try { script = getIntegrationScript(this.integration); } catch (e) { - logger.incoming.warn(e); + incomingLogger.error(e); return API.v1.failure(e.message); } @@ -214,7 +210,7 @@ function executeIntegrationRest() { })).wait(); if (!result) { - logger.incoming.debug('[Process Incoming Request result of Trigger', this.integration.name, ':] No data'); + incomingLogger.debug({ msg: 'Process Incoming Request result of Trigger has no data', name: this.integration.name }); return API.v1.success(); } if (result && result.error) { return API.v1.failure(result.error); @@ -226,13 +222,9 @@ function executeIntegrationRest() { this.user = result.user; } - logger.incoming.debug('[Process Incoming Request result of Trigger', this.integration.name, ':]'); - logger.incoming.debug('result', this.bodyParams); - } catch ({ stack }) { - logger.incoming.error('[Error running Script in Trigger', this.integration.name, ':]'); - logger.incoming.error(this.integration.scriptCompiled.replace(/^/gm, ' ')); - logger.incoming.error('[Stack:]'); - logger.incoming.error(stack.replace(/^/gm, ' ')); + incomingLogger.debug({ msg: 'Process Incoming Request result of Trigger', name: this.integration.name, result: this.bodyParams }); + } catch (err) { + incomingLogger.error({ msg: 'Error running Script in Trigger', name: this.integration.name, script: this.integration.scriptCompiled, err }); return API.v1.failure('error-running-script'); } } @@ -253,7 +245,7 @@ function executeIntegrationRest() { } if (this.scriptResponse) { - logger.incoming.debug('response', this.scriptResponse); + incomingLogger.debug({ msg: 'response', response: this.scriptResponse }); } return API.v1.success(this.scriptResponse); @@ -271,7 +263,7 @@ function removeIntegrationRest() { } function integrationSampleRest() { - logger.incoming.info('Sample Integration'); + incomingLogger.info('Sample Integration'); return { statusCode: 200, body: [ @@ -308,7 +300,7 @@ function integrationSampleRest() { } function integrationInfoRest() { - logger.incoming.info('Info integration'); + incomingLogger.info('Info integration'); return { statusCode: 200, body: { @@ -387,7 +379,7 @@ const Api = new WebHookAPI({ }); if (!this.integration) { - logger.incoming.info('Invalid integration id', this.request.params.integrationId, 'or token', this.request.params.token); + incomingLogger.info(`Invalid integration id ${ this.request.params.integrationId } or token ${ this.request.params.token }`); return { error: { diff --git a/app/integrations/server/lib/triggerHandler.js b/app/integrations/server/lib/triggerHandler.js index a7cd0a682c4a..0c5afb6cbde8 100644 --- a/app/integrations/server/lib/triggerHandler.js +++ b/app/integrations/server/lib/triggerHandler.js @@ -12,7 +12,7 @@ import Future from 'fibers/future'; import * as Models from '../../../models'; import { settings } from '../../../settings'; import { getRoomByNameOrIdWithOptionToJoin, processWebhookMessage } from '../../../lib'; -import { logger } from '../logger'; +import { outgoingLogger } from '../logger'; import { integrations } from '../../lib/rocketchat'; export class RocketChatIntegrationHandler { @@ -26,17 +26,17 @@ export class RocketChatIntegrationHandler { } addIntegration(record) { - logger.outgoing.debug(`Adding the integration ${ record.name } of the event ${ record.event }!`); + outgoingLogger.debug(`Adding the integration ${ record.name } of the event ${ record.event }!`); let channels; if (record.event && !integrations.outgoingEvents[record.event].use.channel) { - logger.outgoing.debug('The integration doesnt rely on channels.'); + outgoingLogger.debug('The integration doesnt rely on channels.'); // We don't use any channels, so it's special ;) channels = ['__any']; } else if (_.isEmpty(record.channel)) { - logger.outgoing.debug('The integration had an empty channel property, so it is going on all the public channels.'); + outgoingLogger.debug('The integration had an empty channel property, so it is going on all the public channels.'); channels = ['all_public_channels']; } else { - logger.outgoing.debug('The integration is going on these channels:', record.channel); + outgoingLogger.debug('The integration is going on these channels:', record.channel); channels = [].concat(record.channel); } @@ -172,11 +172,11 @@ export class RocketChatIntegrationHandler { // If no room could be found, we won't be sending any messages but we'll warn in the logs if (!tmpRoom) { - logger.outgoing.warn(`The Integration "${ trigger.name }" doesn't have a room configured nor did it provide a room to send the message to.`); + outgoingLogger.warn(`The Integration "${ trigger.name }" doesn't have a room configured nor did it provide a room to send the message to.`); return; } - logger.outgoing.debug(`Found a room for ${ trigger.name } which is: ${ tmpRoom.name } with a type of ${ tmpRoom.t }`); + outgoingLogger.debug(`Found a room for ${ trigger.name } which is: ${ tmpRoom.name } with a type of ${ tmpRoom.t }`); message.bot = { i: trigger._id }; @@ -240,8 +240,8 @@ export class RocketChatIntegrationHandler { let vmScript; try { - logger.outgoing.info('Will evaluate script of Trigger', integration.name); - logger.outgoing.debug(script); + outgoingLogger.info({ msg: 'Will evaluate script of Trigger', name: integration.name }); + outgoingLogger.debug(script); vmScript = this.vm.createScript(script, 'script.js'); @@ -256,16 +256,13 @@ export class RocketChatIntegrationHandler { return this.compiledScripts[integration._id].script; } - } catch (e) { - logger.outgoing.error(`Error evaluating Script in Trigger ${ integration.name }:`); - logger.outgoing.error(script.replace(/^/gm, ' ')); - logger.outgoing.error('Stack Trace:'); - logger.outgoing.error(e.stack.replace(/^/gm, ' ')); + } catch (err) { + outgoingLogger.error({ msg: 'Error evaluating Script in Trigger', name: integration.name, script, err }); throw new Meteor.Error('error-evaluating-script'); } if (!sandbox.Script) { - logger.outgoing.error(`Class "Script" not in Trigger ${ integration.name }:`); + outgoingLogger.error(`Class "Script" not in Trigger ${ integration.name }:`); throw new Meteor.Error('class-script-not-found'); } } @@ -295,7 +292,7 @@ export class RocketChatIntegrationHandler { } if (!script[method]) { - logger.outgoing.error(`Method "${ method }" no found in the Integration "${ integration.name }"`); + outgoingLogger.error(`Method "${ method }" no found in the Integration "${ integration.name }"`); this.updateHistory({ historyId, step: `execute-script-no-method-${ method }` }); return; } @@ -323,16 +320,13 @@ export class RocketChatIntegrationHandler { timeout: 3000, })).wait(); - logger.outgoing.debug(`Script method "${ method }" result of the Integration "${ integration.name }" is:`); - logger.outgoing.debug(result); + outgoingLogger.debug({ msg: `Script method "${ method }" result of the Integration "${ integration.name }" is:`, result }); return result; - } catch (e) { - this.updateHistory({ historyId, step: `execute-script-error-running-${ method }`, error: true, errorStack: e.stack.replace(/^/gm, ' ') }); - logger.outgoing.error(`Error running Script in the Integration ${ integration.name }:`); - logger.outgoing.debug(integration.scriptCompiled.replace(/^/gm, ' ')); // Only output the compiled script if debugging is enabled, so the logs don't get spammed. - logger.outgoing.error('Stack:'); - logger.outgoing.error(e.stack.replace(/^/gm, ' ')); + } catch (err) { + this.updateHistory({ historyId, step: `execute-script-error-running-${ method }`, error: true, errorStack: err.stack.replace(/^/gm, ' ') }); + outgoingLogger.error({ msg: 'Error running Script in the Integration', name: integration.name, err }); + outgoingLogger.debug({ msg: 'Error running Script in the Integration', name: integration.name, script: integration.scriptCompiled }); // Only output the compiled script if debugging is enabled, so the logs don't get spammed. } } @@ -381,12 +375,12 @@ export class RocketChatIntegrationHandler { } break; default: - logger.outgoing.warn(`An Unhandled Trigger Event was called: ${ argObject.event }`); + outgoingLogger.warn(`An Unhandled Trigger Event was called: ${ argObject.event }`); argObject.event = undefined; break; } - logger.outgoing.debug(`Got the event arguments for the event: ${ argObject.event }`, argObject); + outgoingLogger.debug({ msg: `Got the event arguments for the event: ${ argObject.event }`, argObject }); return argObject; } @@ -546,7 +540,7 @@ export class RocketChatIntegrationHandler { } executeTriggers(...args) { - logger.outgoing.debug('Execute Trigger:', args[0]); + outgoingLogger.debug({ msg: 'Execute Trigger:', arg: args[0] }); const argObject = this.eventNameArgumentsToObject(...args); const { event, message, room } = argObject; @@ -558,7 +552,7 @@ export class RocketChatIntegrationHandler { return; } - logger.outgoing.debug('Starting search for triggers for the room:', room ? room._id : '__any'); + outgoingLogger.debug(`Starting search for triggers for the room: ${ room ? room._id : '__any' }`); const triggersToExecute = this.getTriggersToExecute(room, message); @@ -569,10 +563,10 @@ export class RocketChatIntegrationHandler { } } - logger.outgoing.debug(`Found ${ triggersToExecute.length } to iterate over and see if the match the event.`); + outgoingLogger.debug(`Found ${ triggersToExecute.length } to iterate over and see if the match the event.`); for (const triggerToExecute of triggersToExecute) { - logger.outgoing.debug(`Is "${ triggerToExecute.name }" enabled, ${ triggerToExecute.enabled }, and what is the event? ${ triggerToExecute.event }`); + outgoingLogger.debug(`Is "${ triggerToExecute.name }" enabled, ${ triggerToExecute.enabled }, and what is the event? ${ triggerToExecute.event }`); if (triggerToExecute.enabled === true && triggerToExecute.event === event) { this.executeTrigger(triggerToExecute, argObject); } @@ -587,11 +581,11 @@ export class RocketChatIntegrationHandler { executeTriggerUrl(url, trigger, { event, message, room, owner, user }, theHistoryId, tries = 0) { if (!this.isTriggerEnabled(trigger)) { - logger.outgoing.warn(`The trigger "${ trigger.name }" is no longer enabled, stopping execution of it at try: ${ tries }`); + outgoingLogger.warn(`The trigger "${ trigger.name }" is no longer enabled, stopping execution of it at try: ${ tries }`); return; } - logger.outgoing.debug(`Starting to execute trigger: ${ trigger.name } (${ trigger._id })`); + outgoingLogger.debug(`Starting to execute trigger: ${ trigger.name } (${ trigger._id })`); let word; // Not all triggers/events support triggerWords @@ -609,14 +603,14 @@ export class RocketChatIntegrationHandler { // Stop if there are triggerWords but none match if (!word) { - logger.outgoing.debug(`The trigger word which "${ trigger.name }" was expecting could not be found, not executing.`); + outgoingLogger.debug(`The trigger word which "${ trigger.name }" was expecting could not be found, not executing.`); return; } } } if (message && message.editedAt && !trigger.runOnEdits) { - logger.outgoing.debug(`The trigger "${ trigger.name }"'s run on edits is disabled and the message was edited.`); + outgoingLogger.debug(`The trigger "${ trigger.name }"'s run on edits is disabled and the message was edited.`); return; } @@ -634,8 +628,8 @@ export class RocketChatIntegrationHandler { this.mapEventArgsToData(data, { trigger, event, message, room, owner, user }); this.updateHistory({ historyId, step: 'mapped-args-to-data', data, triggerWord: word }); - logger.outgoing.info(`Will be executing the Integration "${ trigger.name }" to the url: ${ url }`); - logger.outgoing.debug(data); + outgoingLogger.info(`Will be executing the Integration "${ trigger.name }" to the url: ${ url }`); + outgoingLogger.debug(data); let opts = { params: {}, @@ -676,9 +670,9 @@ export class RocketChatIntegrationHandler { this.updateHistory({ historyId, step: 'pre-http-call', url: opts.url, httpCallData: opts.data }); HTTP.call(opts.method, opts.url, opts, (error, result) => { if (!result) { - logger.outgoing.warn(`Result for the Integration ${ trigger.name } to ${ url } is empty`); + outgoingLogger.warn(`Result for the Integration ${ trigger.name } to ${ url } is empty`); } else { - logger.outgoing.info(`Status code for the Integration ${ trigger.name } to ${ url } is ${ result.statusCode }`); + outgoingLogger.info(`Status code for the Integration ${ trigger.name } to ${ url } is ${ result.statusCode }`); } this.updateHistory({ historyId, step: 'after-http-call', httpError: error, httpResult: result }); @@ -712,25 +706,22 @@ export class RocketChatIntegrationHandler { // if the result contained nothing or wasn't a successful statusCode if (!result || !this.successResults.includes(result.statusCode)) { if (error) { - logger.outgoing.error(`Error for the Integration "${ trigger.name }" to ${ url } is:`); - logger.outgoing.error(error); + outgoingLogger.error({ msg: `Error for the Integration "${ trigger.name }" to ${ url }`, err: error }); } if (result) { - logger.outgoing.error(`Error for the Integration "${ trigger.name }" to ${ url } is:`); - logger.outgoing.error(result); + outgoingLogger.error({ msg: `Error for the Integration "${ trigger.name }" to ${ url }`, result }); if (result.statusCode === 410) { this.updateHistory({ historyId, step: 'after-process-http-status-410', error: true }); - logger.outgoing.error(`Disabling the Integration "${ trigger.name }" because the status code was 401 (Gone).`); + outgoingLogger.error(`Disabling the Integration "${ trigger.name }" because the status code was 401 (Gone).`); Models.Integrations.update({ _id: trigger._id }, { $set: { enabled: false } }); return; } if (result.statusCode === 500) { this.updateHistory({ historyId, step: 'after-process-http-status-500', error: true }); - logger.outgoing.error(`Error "500" for the Integration "${ trigger.name }" to ${ url }.`); - logger.outgoing.error(result.content); + outgoingLogger.error({ msg: `Error "500" for the Integration "${ trigger.name }" to ${ url }.`, content: result.content }); return; } } @@ -760,7 +751,7 @@ export class RocketChatIntegrationHandler { return; } - logger.outgoing.info(`Trying the Integration ${ trigger.name } to ${ url } again in ${ waitTime } milliseconds.`); + outgoingLogger.info(`Trying the Integration ${ trigger.name } to ${ url } again in ${ waitTime } milliseconds.`); Meteor.setTimeout(() => { this.executeTriggerUrl(url, trigger, { event, message, room, owner, user }, historyId, tries + 1); }, waitTime); diff --git a/app/integrations/server/logger.js b/app/integrations/server/logger.js index 4a293574b984..dd0076279883 100644 --- a/app/integrations/server/logger.js +++ b/app/integrations/server/logger.js @@ -1,8 +1,6 @@ import { Logger } from '../../logger'; -export const logger = new Logger('Integrations', { - sections: { - incoming: 'Incoming WebHook', - outgoing: 'Outgoing WebHook', - }, -}); +const logger = new Logger('Integrations'); + +export const incomingLogger = logger.section('Incoming WebHook'); +export const outgoingLogger = logger.section('Outgoing WebHook'); diff --git a/app/irc/server/irc-bridge/index.js b/app/irc/server/irc-bridge/index.js index c796720c471d..8f296f847e95 100644 --- a/app/irc/server/irc-bridge/index.js +++ b/app/irc/server/irc-bridge/index.js @@ -5,9 +5,13 @@ import _ from 'underscore'; import * as peerCommandHandlers from './peerHandlers'; import * as localCommandHandlers from './localHandlers'; -import { callbacks } from '../../../callbacks'; +import { callbacks } from '../../../callbacks/server'; import * as servers from '../servers'; import { Settings } from '../../../models/server'; +import { Logger } from '../../../logger/server'; + +const logger = new Logger('IRC Bridge'); +const queueLogger = logger.section('Queue'); let removed = false; const updateLastPing = _.throttle(Meteor.bindEnvironment(() => { @@ -82,11 +86,13 @@ class Bridge { * Log helper */ log(message) { - console.log(`[irc][bridge] ${ message }`); + // TODO logger: debug? + logger.info(message); } logQueue(message) { - console.log(`[irc][bridge][queue] ${ message }`); + // TODO logger: debug? + queueLogger.info(message); } /** diff --git a/app/irc/server/irc-bridge/localHandlers/onSaveMessage.js b/app/irc/server/irc-bridge/localHandlers/onSaveMessage.js index a5ebf1ddfb82..aed761ff127b 100644 --- a/app/irc/server/irc-bridge/localHandlers/onSaveMessage.js +++ b/app/irc/server/irc-bridge/localHandlers/onSaveMessage.js @@ -1,3 +1,4 @@ +import { SystemLogger } from '../../../../../server/lib/logger/system'; import { Subscriptions, Users } from '../../../../models'; export default function handleOnSaveMessage(message, to) { @@ -21,7 +22,7 @@ export default function handleOnSaveMessage(message, to) { }); if (!toIdentification) { - console.error('[irc][server] Target user not found'); + SystemLogger.error('[irc][server] Target user not found'); return; } } else { diff --git a/app/irc/server/servers/RFC2813/index.js b/app/irc/server/servers/RFC2813/index.js index 6d6335c4017b..77750b9d1059 100644 --- a/app/irc/server/servers/RFC2813/index.js +++ b/app/irc/server/servers/RFC2813/index.js @@ -5,6 +5,9 @@ import { EventEmitter } from 'events'; import parseMessage from './parseMessage'; import peerCommandHandlers from './peerCommandHandlers'; import localCommandHandlers from './localCommandHandlers'; +import { Logger } from '../../../../logger/server'; + +const logger = new Logger('IRC Server'); class RFC2813 { constructor(config) { @@ -35,7 +38,7 @@ class RFC2813 { this.socket.on('data', this.onReceiveFromPeer.bind(this)); this.socket.on('connect', this.onConnect.bind(this)); - this.socket.on('error', (err) => console.log('[irc][server][err]', err)); + this.socket.on('error', (err) => logger.error(err)); this.socket.on('timeout', () => this.log('Timeout')); this.socket.on('close', () => this.log('Connection Closed')); // Setup local @@ -46,7 +49,8 @@ class RFC2813 { * Log helper */ log(message) { - console.log(`[irc][server] ${ message }`); + // TODO logger: debug? + logger.info(message); } /** @@ -148,11 +152,11 @@ class RFC2813 { const command = peerCommandHandlers[parsedMessage.command].call(this, parsedMessage); if (command) { - this.log(`Emitting peer command to local: ${ JSON.stringify(command) }`); + this.log({ msg: 'Emitting peer command to local', command }); this.emit('peerCommand', command); } } else { - this.log(`Unhandled peer message: ${ JSON.stringify(parsedMessage) }`); + this.log({ msg: 'Unhandled peer message', parsedMessage }); } } }); @@ -171,7 +175,7 @@ class RFC2813 { localCommandHandlers[command].call(this, parameters, this); } else { - this.log(`Unhandled local command: ${ JSON.stringify(command) }`); + this.log({ msg: 'Unhandled local command', command }); } } } diff --git a/app/ldap/server/ldap.js b/app/ldap/server/ldap.js index eafdd3161796..a3bae173b835 100644 --- a/app/ldap/server/ldap.js +++ b/app/ldap/server/ldap.js @@ -6,14 +6,12 @@ import { callbacks } from '../../callbacks/server'; import { settings } from '../../settings'; import { Logger } from '../../logger'; -const logger = new Logger('LDAP', { - sections: { - connection: 'Connection', - bind: 'Bind', - search: 'Search', - auth: 'Auth', - }, -}); +const logger = new Logger('LDAP'); + +export const connLogger = logger.section('Connection'); +export const bindLogger = logger.section('Bind'); +export const searchLogger = logger.section('Search'); +export const authLogger = logger.section('Auth'); export default class LDAP { constructor() { @@ -66,7 +64,7 @@ export default class LDAP { } connectAsync(callback) { - logger.connection.info('Init setup'); + connLogger.info('Init setup'); let replied = false; @@ -113,15 +111,15 @@ export default class LDAP { connectionOptions.url = `ldap://${ connectionOptions.url }`; } - logger.connection.info('Connecting', connectionOptions.url); - logger.connection.debug('connectionOptions', connectionOptions); + connLogger.info({ msg: 'Connecting', url: connectionOptions.url }); + connLogger.debug({ msg: 'connectionOptions', connectionOptions }); this.client = ldapjs.createClient(connectionOptions); this.bindSync = Meteor.wrapAsync(this.client.bind, this.client); this.client.on('error', (error) => { - logger.connection.error('connection', error); + connLogger.error({ msg: 'connection', err: error }); if (replied === false) { replied = true; callback(error, null); @@ -129,12 +127,12 @@ export default class LDAP { }); this.client.on('idle', () => { - logger.search.info('Idle'); + searchLogger.info('Idle'); this.disconnect(); }); this.client.on('close', () => { - logger.search.info('Closed'); + searchLogger.info('Closed'); }); if (this.options.encryption === 'tls') { @@ -143,12 +141,12 @@ export default class LDAP { // https://github.com/mcavage/node-ldapjs/issues/349 tlsOptions.host = this.options.host; - logger.connection.info('Starting TLS'); - logger.connection.debug('tlsOptions', tlsOptions); + connLogger.info('Starting TLS'); + connLogger.debug({ tlsOptions }); this.client.starttls(tlsOptions, null, (error, response) => { if (error) { - logger.connection.error('TLS connection', error); + connLogger.error({ msg: 'TLS connection', err: error }); if (replied === false) { replied = true; callback(error, null); @@ -156,7 +154,7 @@ export default class LDAP { return; } - logger.connection.info('TLS connected'); + connLogger.info('TLS connected'); this.connected = true; if (replied === false) { replied = true; @@ -165,7 +163,7 @@ export default class LDAP { }); } else { this.client.on('connect', (response) => { - logger.connection.info('LDAP connected'); + connLogger.info('LDAP connected'); this.connected = true; if (replied === false) { replied = true; @@ -176,7 +174,7 @@ export default class LDAP { setTimeout(() => { if (replied === false) { - logger.connection.error('connection time out', connectionOptions.connectTimeout); + connLogger.error({ msg: 'connection time out', connectTimeout: connectionOptions.connectTimeout }); replied = true; callback(new Error('Timeout')); } @@ -216,7 +214,7 @@ export default class LDAP { return; } - logger.bind.info('Binding UserDN', this.options.Authentication_UserDN); + bindLogger.info({ msg: 'Binding UserDN', userDN: this.options.Authentication_UserDN }); this.bindSync(this.options.Authentication_UserDN, this.options.Authentication_Password); this.domainBinded = true; } @@ -237,9 +235,8 @@ export default class LDAP { }; } - logger.search.info('Searching user', username); - logger.search.debug('searchOptions', searchOptions); - logger.search.debug('BaseDN', this.options.BaseDN); + searchLogger.info({ msg: 'Searching user', username }); + searchLogger.debug({ searchOptions, BaseDN: this.options.BaseDN }); if (page) { return this.searchAllPaged(this.options.BaseDN, searchOptions, page); @@ -278,9 +275,8 @@ export default class LDAP { attributes: ['*', '+'], }; - logger.search.info('Searching by id', id); - logger.search.debug('search filter', searchOptions.filter.toString()); - logger.search.debug('BaseDN', this.options.BaseDN); + searchLogger.info({ msg: 'Searching by id', id }); + searchLogger.debug({ msg: 'search filter', filter: searchOptions.filter, BaseDN: this.options.BaseDN }); const result = this.searchAllSync(this.options.BaseDN, searchOptions); @@ -289,7 +285,7 @@ export default class LDAP { } if (result.length > 1) { - logger.search.error('Search by id', id, 'returned', result.length, 'records'); + searchLogger.error(`Search by id ${ id } returned ${ result.length } records`); } return result[0]; @@ -303,9 +299,8 @@ export default class LDAP { scope: this.options.User_Search_Scope || 'sub', }; - logger.search.info('Searching user', username); - logger.search.debug('searchOptions', searchOptions); - logger.search.debug('BaseDN', this.options.BaseDN); + searchLogger.info({ msg: 'Searching user', username }); + searchLogger.debug({ searchOptions, BaseDN: this.options.BaseDN }); const result = this.searchAllSync(this.options.BaseDN, searchOptions); @@ -314,7 +309,7 @@ export default class LDAP { } if (result.length > 1) { - logger.search.error('Search by username', username, 'returned', result.length, 'records'); + searchLogger.error(`Search by username ${ username } returned ${ result.length } records`); } return result[0]; @@ -345,7 +340,7 @@ export default class LDAP { scope: 'sub', }; - logger.search.debug('Group filter LDAP:', searchOptions.filter); + searchLogger.debug({ msg: 'Group filter LDAP:', filter: searchOptions.filter }); const result = this.searchAllSync(this.options.BaseDN, searchOptions); @@ -389,7 +384,7 @@ export default class LDAP { ({ BaseDN, options } = callbacks.run('ldap.beforeSearchAll', { BaseDN, options })); const processPage = ({ entries, title, end, next }) => { - logger.search.info(title); + searchLogger.info(title); // Force LDAP idle to wait the record processing this.client._updateIdle(true); page(null, entries, { end, @@ -402,13 +397,13 @@ export default class LDAP { this.client.search(BaseDN, options, (error, res) => { if (error) { - logger.search.error(error); + searchLogger.error(error); page(error); return; } res.on('error', (error) => { - logger.search.error(error); + searchLogger.error(error); page(error); }); @@ -469,13 +464,13 @@ export default class LDAP { this.client.search(BaseDN, options, (error, res) => { if (error) { - logger.search.error(error); + searchLogger.error(error); callback(error); return; } res.on('error', (error) => { - logger.search.error(error); + searchLogger.error(error); callback(error); }); @@ -486,14 +481,14 @@ export default class LDAP { }); res.on('end', () => { - logger.search.info('Search result count', entries.length); + searchLogger.info(`Search result count ${ entries.length }`); callback(null, entries); }); }); } authSync(dn, password) { - logger.auth.info('Authenticating', dn); + authLogger.info({ msg: 'Authenticating', dn }); try { this.bindSync(dn, password); @@ -503,15 +498,15 @@ export default class LDAP { }; const result = this.searchAllSync(dn, searchOptions); if (result.length === 0) { - logger.auth.info('Bind successful but user was not found via search', dn, searchOptions); + authLogger.info({ msg: 'Bind successful but user was not found via search', dn, searchOptions }); return false; } } - logger.auth.info('Authenticated', dn); + authLogger.info({ msg: 'Authenticated', dn }); return true; } catch (error) { - logger.auth.info('Not authenticated', dn); - logger.auth.debug('error', error); + authLogger.info({ msg: 'Not authenticated', dn }); + authLogger.debug(error); return false; } } @@ -519,7 +514,7 @@ export default class LDAP { disconnect() { this.connected = false; this.domainBinded = false; - logger.connection.info('Disconecting'); + connLogger.info('Disconecting'); this.client.unbind(); } } diff --git a/app/ldap/server/loginHandler.js b/app/ldap/server/loginHandler.js index 79425c9dfe74..4f271b49ee6c 100644 --- a/app/ldap/server/loginHandler.js +++ b/app/ldap/server/loginHandler.js @@ -10,7 +10,7 @@ import { callbacks } from '../../callbacks'; import { Logger } from '../../logger'; -const logger = new Logger('LDAPHandler', {}); +const logger = new Logger('LDAPHandler'); function fallbackDefaultAccountSystem(bind, username, password) { if (typeof username === 'string') { diff --git a/app/ldap/server/sync.js b/app/ldap/server/sync.js index f4f0c65f993b..23cbe47c8304 100644 --- a/app/ldap/server/sync.js +++ b/app/ldap/server/sync.js @@ -16,7 +16,7 @@ import { FileUpload } from '../../file-upload'; import { addUserToRoom, removeUserFromRoom, createRoom, saveUserIdentity } from '../../lib/server/functions'; import { api } from '../../../server/sdk/api'; -export const logger = new Logger('LDAPSync', {}); +export const logger = new Logger('LDAPSync'); export function isUserInLDAPGroup(ldap, ldapUser, user, ldapGroup) { const syncUserRolesFilter = settings.get('LDAP_Sync_User_Data_Groups_Filter').trim(); @@ -392,7 +392,7 @@ export function syncUserData(user, ldapUser, ldap) { const userChannels = mapLDAPGroupsToChannels(ldap, ldapUser, user); if (user && user._id && userData) { - logger.debug('setting', JSON.stringify(userData, null, 2)); + logger.debug({ msg: 'setting', userData }); if (userData.name) { _setRealName(user._id, userData.name); delete userData.name; diff --git a/app/ldap/server/testConnection.js b/app/ldap/server/testConnection.js index 1511a944e238..98be62dcb991 100644 --- a/app/ldap/server/testConnection.js +++ b/app/ldap/server/testConnection.js @@ -1,8 +1,9 @@ import { Meteor } from 'meteor/meteor'; import LDAP from './ldap'; -import { hasRole } from '../../authorization'; -import { settings } from '../../settings'; +import { hasRole } from '../../authorization/server'; +import { settings } from '../../settings/server'; +import { SystemLogger } from '../../../server/lib/logger/system'; Meteor.methods({ ldap_test_connection() { @@ -24,7 +25,7 @@ Meteor.methods({ ldap = new LDAP(); ldap.connectSync(); } catch (error) { - console.log(error); + SystemLogger.error(error); throw new Meteor.Error(error.message); } diff --git a/app/lib/server/functions/processWebhookMessage.js b/app/lib/server/functions/processWebhookMessage.js index 63eeeb16252b..c487bd84a89b 100644 --- a/app/lib/server/functions/processWebhookMessage.js +++ b/app/lib/server/functions/processWebhookMessage.js @@ -6,13 +6,14 @@ import mem from 'mem'; import { getRoomByNameOrIdWithOptionToJoin } from './getRoomByNameOrIdWithOptionToJoin'; import { sendMessage } from './sendMessage'; import { validateRoomMessagePermissions } from '../../../authorization/server/functions/canSendMessage'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { getDirectMessageByIdWithOptionToJoin, getDirectMessageByNameOrIdWithOptionToJoin } from './getDirectMessageByNameOrIdWithOptionToJoin'; // show deprecation warning only once per hour for each integration const showDeprecation = mem(({ integration, channels, username }, error) => { console.warn(`Warning: The integration "${ integration }" failed to send a message to "${ [].concat(channels).join(',') }" because user "${ username }" doesn't have permission or is not a member of the channel.`); console.warn('This behavior is deprecated and starting from version v4.0.0 the following error will be thrown and the message will not be sent.'); - console.error(error); + SystemLogger.error(error); }, { maxAge: 360000, cacheKey: (integration) => JSON.stringify(integration) }); export const processWebhookMessage = function(messageObj, user, defaultValues = { channel: '', alias: '', avatar: '', emoji: '' }, integration = null) { @@ -52,7 +53,7 @@ export const processWebhookMessage = function(messageObj, user, defaultValues = } if (messageObj.attachments && !Array.isArray(messageObj.attachments)) { - console.log('Attachments should be Array, ignoring value'.red, messageObj.attachments); + SystemLogger.warn({ msg: 'Attachments should be Array, ignoring value', attachments: messageObj.attachments }); messageObj.attachments = undefined; } diff --git a/app/lib/server/functions/sendMessage.js b/app/lib/server/functions/sendMessage.js index a8b38a0b6f8f..c8c2420e928e 100644 --- a/app/lib/server/functions/sendMessage.js +++ b/app/lib/server/functions/sendMessage.js @@ -8,6 +8,7 @@ import { Apps } from '../../../apps/server'; import { isURL, isRelativeURL } from '../../../utils/lib/isURL'; import { FileUpload } from '../../../file-upload/server'; import { hasPermission } from '../../../authorization/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { parseUrlsInMessage } from './parseUrlsInMessage'; const { DISABLE_MESSAGE_PARSER = 'false' } = process.env; @@ -197,7 +198,7 @@ export const sendMessage = function(user, message, room, upsert = false) { const prevent = Promise.await(Apps.getBridges().getListenerBridge().messageEvent('IPreMessageSentPrevent', message)); if (prevent) { if (settings.get('Apps_Framework_Development_Mode')) { - console.log('A Rocket.Chat App prevented the message sending.', message); + SystemLogger.info({ msg: 'A Rocket.Chat App prevented the message sending.', message }); } return; @@ -223,7 +224,7 @@ export const sendMessage = function(user, message, room, upsert = false) { message.md = parser(message.msg); } } catch (e) { - console.log(e); // errors logged while the parser is at experimental stage + SystemLogger.error(e); // errors logged while the parser is at experimental stage } if (message) { if (message._id && upsert) { diff --git a/app/lib/server/functions/setUserAvatar.js b/app/lib/server/functions/setUserAvatar.js index ecc6e88e895f..5bcd36224583 100644 --- a/app/lib/server/functions/setUserAvatar.js +++ b/app/lib/server/functions/setUserAvatar.js @@ -1,9 +1,10 @@ import { Meteor } from 'meteor/meteor'; import { HTTP } from 'meteor/http'; -import { RocketChatFile } from '../../../file'; -import { FileUpload } from '../../../file-upload'; -import { Users } from '../../../models'; +import { RocketChatFile } from '../../../file/server'; +import { FileUpload } from '../../../file-upload/server'; +import { Users } from '../../../models/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { api } from '../../../../server/sdk/api'; export const setUserAvatar = function(user, dataURI, contentType, service) { @@ -18,23 +19,23 @@ export const setUserAvatar = function(user, dataURI, contentType, service) { try { result = HTTP.get(dataURI, { npmRequestOptions: { encoding: 'binary', rejectUnauthorized: false } }); if (!result) { - console.log(`Not a valid response, from the avatar url: ${ encodeURI(dataURI) }`); + SystemLogger.info(`Not a valid response, from the avatar url: ${ encodeURI(dataURI) }`); throw new Meteor.Error('error-avatar-invalid-url', `Invalid avatar URL: ${ encodeURI(dataURI) }`, { function: 'setUserAvatar', url: dataURI }); } } catch (error) { if (!error.response || error.response.statusCode !== 404) { - console.log(`Error while handling the setting of the avatar from a url (${ encodeURI(dataURI) }) for ${ user.username }:`, error); + SystemLogger.info(`Error while handling the setting of the avatar from a url (${ encodeURI(dataURI) }) for ${ user.username }:`, error); throw new Meteor.Error('error-avatar-url-handling', `Error while handling avatar setting from a URL (${ encodeURI(dataURI) }) for ${ user.username }`, { function: 'RocketChat.setUserAvatar', url: dataURI, username: user.username }); } } if (result.statusCode !== 200) { - console.log(`Not a valid response, ${ result.statusCode }, from the avatar url: ${ dataURI }`); + SystemLogger.info(`Not a valid response, ${ result.statusCode }, from the avatar url: ${ dataURI }`); throw new Meteor.Error('error-avatar-invalid-url', `Invalid avatar URL: ${ dataURI }`, { function: 'setUserAvatar', url: dataURI }); } if (!/image\/.+/.test(result.headers['content-type'])) { - console.log(`Not a valid content-type from the provided url, ${ result.headers['content-type'] }, from the avatar url: ${ dataURI }`); + SystemLogger.info(`Not a valid content-type from the provided url, ${ result.headers['content-type'] }, from the avatar url: ${ dataURI }`); throw new Meteor.Error('error-avatar-invalid-url', `Invalid avatar URL: ${ dataURI }`, { function: 'setUserAvatar', url: dataURI }); } diff --git a/app/lib/server/functions/setUsername.js b/app/lib/server/functions/setUsername.js index 832db3defcf8..8795fb6b01fc 100644 --- a/app/lib/server/functions/setUsername.js +++ b/app/lib/server/functions/setUsername.js @@ -9,6 +9,7 @@ import { RateLimiter } from '../lib'; import { addUserToRoom } from './addUserToRoom'; import { api } from '../../../../server/sdk/api'; import { checkUsernameAvailability, setUserAvatar, getAvatarSuggestionForUser } from '.'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export const _setUsername = function(userId, u, fullUser) { const username = s.trim(u); @@ -44,7 +45,7 @@ export const _setUsername = function(userId, u, fullUser) { }); } } catch (e) { - console.error(e); + SystemLogger.error(e); } // Set new username* Users.setUsername(user._id, username); diff --git a/app/lib/server/functions/updateMessage.js b/app/lib/server/functions/updateMessage.js index eaa60b0318b5..bf68daf712d6 100644 --- a/app/lib/server/functions/updateMessage.js +++ b/app/lib/server/functions/updateMessage.js @@ -1,9 +1,10 @@ import { Meteor } from 'meteor/meteor'; import { parser } from '@rocket.chat/message-parser'; -import { Messages, Rooms } from '../../../models'; -import { settings } from '../../../settings'; -import { callbacks } from '../../../callbacks'; +import { Messages, Rooms } from '../../../models/server'; +import { settings } from '../../../settings/server'; +import { callbacks } from '../../../callbacks/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { Apps } from '../../../apps/server'; import { parseUrlsInMessage } from './parseUrlsInMessage'; @@ -52,7 +53,7 @@ export const updateMessage = function(message, user, originalMessage) { message.md = parser(message.msg); } } catch (e) { - console.log(e); // errors logged while the parser is at experimental stage + SystemLogger.error(e); // errors logged while the parser is at experimental stage } const tempid = message._id; diff --git a/app/lib/server/index.js b/app/lib/server/index.js index 5a89c8e44a35..78040f70c273 100644 --- a/app/lib/server/index.js +++ b/app/lib/server/index.js @@ -10,7 +10,6 @@ import '../lib/MessageTypes'; import '../startup'; import '../startup/defaultRoomTypes'; import './lib/bugsnag'; -import './lib/configLogger'; import './lib/debug'; import './lib/loginErrorMessageOverride'; import './oauth/oauth'; diff --git a/app/lib/server/lib/configLogger.js b/app/lib/server/lib/configLogger.js deleted file mode 100644 index 3039cc628598..000000000000 --- a/app/lib/server/lib/configLogger.js +++ /dev/null @@ -1,19 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { LoggerManager } from '../../../logger'; -import { settings } from '../../../settings'; - -settings.get('Log_Package', function(key, value) { - LoggerManager.showPackage = value; -}); - -settings.get('Log_File', function(key, value) { - LoggerManager.showFileAndLine = value; -}); - -settings.get('Log_Level', function(key, value) { - if (value != null) { - LoggerManager.logLevel = parseInt(value); - Meteor.setTimeout(() => LoggerManager.enable(true), 200); - } -}); diff --git a/app/lib/server/lib/debug.js b/app/lib/server/lib/debug.js index 0fb22935c534..2d37b333468e 100644 --- a/app/lib/server/lib/debug.js +++ b/app/lib/server/lib/debug.js @@ -3,27 +3,12 @@ import { WebApp } from 'meteor/webapp'; import { InstanceStatus } from 'meteor/konecty:multiple-instances-status'; import _ from 'underscore'; -import { settings } from '../../../settings'; -import { metrics } from '../../../metrics'; -import { Logger } from '../../../logger'; - -const logger = new Logger('Meteor', { - methods: { - method: { - type: 'info', - }, - publish: { - type: 'debug', - }, - }, -}); - -const { - LOG_METHOD_PAYLOAD = 'false', - LOG_REST_METHOD_PAYLOADS = 'false', -} = process.env; +import { settings } from '../../../settings/server'; +import { metrics } from '../../../metrics/server'; +import { Logger } from '../../../../server/lib/logger/Logger'; +import { getMethodArgs } from '../../../../server/lib/logger/logPayloads'; -const addPayloadToLog = LOG_METHOD_PAYLOAD !== 'false' || LOG_REST_METHOD_PAYLOADS !== 'false'; +const logger = new Logger('Meteor'); let Log_Trace_Methods; let Log_Trace_Subscriptions; @@ -56,20 +41,6 @@ const traceConnection = (enable, filter, prefix, name, connection, userId) => { } }; -const omitKeyArgs = (args, name) => { - if (name === 'saveSettings') { - return [args[0].map((arg) => _.omit(arg, 'value'))]; - } - - if (name === 'saveSetting') { - return [args[0], args[2]]; - } - - return args.map((arg) => (typeof arg !== 'object' - ? arg - : _.omit(arg, 'password', 'msg', 'pass', 'username', 'message'))); -}; - const wrapMethods = function(name, originalHandler, methodsMap) { methodsMap[name] = function(...originalArgs) { traceConnection(Log_Trace_Methods, Log_Trace_Methods_Filter, 'method', name, this.connection, this.userId); @@ -81,11 +52,16 @@ const wrapMethods = function(name, originalHandler, methodsMap) { has_connection: this.connection != null, has_user: this.userId != null, }); - const args = name === 'ufsWrite' ? Array.prototype.slice.call(originalArgs, 1) : originalArgs; - const dateTime = new Date().toISOString(); - const userId = Meteor.userId(); - logger.method(() => `${ this.connection?.clientAddress } - ${ userId } [${ dateTime }] "METHOD ${ method }" - "${ this.connection?.httpHeaders.referer }" "${ this.connection?.httpHeaders['user-agent'] }" | ${ addPayloadToLog ? JSON.stringify(omitKeyArgs(args, name)) : '' }`); + logger.method({ + method, + userId: Meteor.userId(), + userAgent: this.connection?.httpHeaders['user-agent'], + referer: this.connection?.httpHeaders.referer, + remoteIP: this.connection?.clientAddress, + instanceId: InstanceStatus.id(), + ...getMethodArgs(name, originalArgs), + }); const result = originalHandler.apply(this, originalArgs); end(); @@ -107,7 +83,16 @@ const originalMeteorPublish = Meteor.publish; Meteor.publish = function(name, func) { return originalMeteorPublish(name, function(...args) { traceConnection(Log_Trace_Subscriptions, Log_Trace_Subscriptions_Filter, 'subscription', name, this.connection, this.userId); - logger.publish(() => `${ name } -> userId: ${ this.userId }, arguments: ${ JSON.stringify(omitKeyArgs(args)) }`); + + logger.subscription({ + publication: name, + userId: this.userId, + userAgent: this.connection?.httpHeaders['user-agent'], + referer: this.connection?.httpHeaders.referer, + remoteIP: this.connection?.clientAddress, + instanceId: InstanceStatus.id(), + }); + const end = metrics.meteorSubscriptions.startTimer({ subscription: name }); const originalReady = this.ready; diff --git a/app/lib/server/lib/interceptDirectReplyEmails.js b/app/lib/server/lib/interceptDirectReplyEmails.js index ed7f022b5313..5447f80f679a 100644 --- a/app/lib/server/lib/interceptDirectReplyEmails.js +++ b/app/lib/server/lib/interceptDirectReplyEmails.js @@ -2,7 +2,8 @@ import { Meteor } from 'meteor/meteor'; import POP3Lib from 'poplib'; import { simpleParser } from 'mailparser'; -import { settings } from '../../../settings'; +import { settings } from '../../../settings/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { IMAPInterceptor } from '../../../../server/email/IMAPInterceptor'; import { processDirectEmail } from '.'; @@ -45,7 +46,7 @@ export class POP3Intercepter { // run on start this.pop3.list(); } else { - console.log('Unable to Log-in ....'); + SystemLogger.info('Unable to Log-in ....'); } })); @@ -61,7 +62,7 @@ export class POP3Intercepter { this.pop3.quit(); } } else { - console.log('Cannot Get Emails ....'); + SystemLogger.info('Cannot Get Emails ....'); } })); @@ -78,7 +79,7 @@ export class POP3Intercepter { // delete email this.pop3.dele(msgnumber); } else { - console.log('Cannot Retrieve Message ....'); + SystemLogger.info('Cannot Retrieve Message ....'); } })); @@ -93,18 +94,18 @@ export class POP3Intercepter { this.pop3.quit(); } } else { - console.log('Cannot Delete Message....'); + SystemLogger.info('Cannot Delete Message....'); } })); // invalid server state this.pop3.on('invalid-state', function(cmd) { - console.log(`Invalid state. You tried calling ${ cmd }`); + SystemLogger.info(`Invalid state. You tried calling ${ cmd }`); }); // locked => command already running, not finished yet this.pop3.on('locked', function(cmd) { - console.log(`Current command has not finished yet. You tried calling ${ cmd }`); + SystemLogger.info(`Current command has not finished yet. You tried calling ${ cmd }`); }); } diff --git a/app/lib/server/lib/processDirectEmail.js b/app/lib/server/lib/processDirectEmail.js index b00a042d476d..3b97938d4694 100644 --- a/app/lib/server/lib/processDirectEmail.js +++ b/app/lib/server/lib/processDirectEmail.js @@ -2,10 +2,11 @@ import { Meteor } from 'meteor/meteor'; import { EmailReplyParser as reply } from 'emailreplyparser'; import moment from 'moment'; -import { settings } from '../../../settings'; -import { Rooms, Messages, Users, Subscriptions } from '../../../models'; -import { metrics } from '../../../metrics'; -import { hasPermission } from '../../../authorization'; +import { settings } from '../../../settings/server'; +import { Rooms, Messages, Users, Subscriptions } from '../../../models/server'; +import { metrics } from '../../../metrics/server'; +import { hasPermission } from '../../../authorization/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { sendMessage as _sendMessage } from '../functions'; export const processDirectEmail = function(email) { @@ -126,6 +127,6 @@ export const processDirectEmail = function(email) { email.headers.mid = email.headers.to.split('@')[0].split('+')[1]; sendMessage(email); } else { - console.log('Invalid Email....If not. Please report it.'); + SystemLogger.error('Invalid Email....If not. Please report it.'); } }; diff --git a/app/lib/server/methods/sendMessage.js b/app/lib/server/methods/sendMessage.js index 3d91d72022d0..871bd69a431f 100644 --- a/app/lib/server/methods/sendMessage.js +++ b/app/lib/server/methods/sendMessage.js @@ -11,7 +11,7 @@ import { Users, Messages } from '../../../models'; import { sendMessage } from '../functions'; import { RateLimiter } from '../lib'; import { canSendMessage } from '../../../authorization/server'; -import { SystemLogger } from '../../../logger/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { api } from '../../../../server/sdk/api'; export function executeSendMessage(uid, message) { diff --git a/app/lib/server/startup/oAuthServicesUpdate.js b/app/lib/server/startup/oAuthServicesUpdate.js index 2e35236f05c5..b414abdab315 100644 --- a/app/lib/server/startup/oAuthServicesUpdate.js +++ b/app/lib/server/startup/oAuthServicesUpdate.js @@ -7,18 +7,12 @@ import { Logger } from '../../../logger'; import { settings } from '../../../settings'; import { addOAuthService } from '../functions/addOAuthService'; -const logger = new Logger('rocketchat:lib', { - methods: { - oauth_updated: { - type: 'info', - }, - }, -}); +const logger = new Logger('rocketchat:lib'); function _OAuthServicesUpdate() { const services = settings.get(/^(Accounts_OAuth_|Accounts_OAuth_Custom-)[a-z0-9_]+$/i); services.forEach((service) => { - logger.oauth_updated(service.key); + logger.info({ oauth_updated: service.key }); let serviceName = service.key.replace('Accounts_OAuth_', ''); if (serviceName === 'Meteor') { serviceName = 'meteor-developer'; diff --git a/app/lib/server/startup/rateLimiter.js b/app/lib/server/startup/rateLimiter.js index f12f23caa8c8..f7339c19958d 100644 --- a/app/lib/server/startup/rateLimiter.js +++ b/app/lib/server/startup/rateLimiter.js @@ -7,7 +7,7 @@ import { settings } from '../../../settings'; import { metrics } from '../../../metrics'; import { Logger } from '../../../logger'; -const logger = new Logger('RateLimiter', {}); +const logger = new Logger('RateLimiter'); // Get initial set of names already registered for rules const names = new Set(Object.values(DDPRateLimiter.printRules()) @@ -111,7 +111,7 @@ const ruleIds = {}; const callback = (message, name) => (reply, input) => { if (reply.allowed === false) { logger.info('DDP RATE LIMIT:', message); - logger.info(JSON.stringify({ ...reply, ...input }, null, 2)); + logger.info({ ...reply, ...input }); metrics.ddpRateLimitExceeded.inc({ limit_name: name, user_id: input.userId, diff --git a/app/lib/server/startup/settings.js b/app/lib/server/startup/settings.js index 1e3e5613e19a..ed49305189c6 100644 --- a/app/lib/server/startup/settings.js +++ b/app/lib/server/startup/settings.js @@ -1605,14 +1605,6 @@ settings.addGroup('Logs', function() { ], public: true, }); - this.add('Log_Package', false, { - type: 'boolean', - public: true, - }); - this.add('Log_File', false, { - type: 'boolean', - public: true, - }); this.add('Log_View_Limit', 1000, { type: 'int', }); diff --git a/app/lib/server/startup/settingsOnLoadDirectReply.js b/app/lib/server/startup/settingsOnLoadDirectReply.js index 73675065cb5b..f38565b79981 100644 --- a/app/lib/server/startup/settingsOnLoadDirectReply.js +++ b/app/lib/server/startup/settingsOnLoadDirectReply.js @@ -1,37 +1,40 @@ import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; +import { Logger } from '../../../logger/server'; import { settings } from '../../../settings'; import { IMAPIntercepter, POP3Helper, POP3 } from '../lib/interceptDirectReplyEmails.js'; +const logger = new Logger('Email Intercepter'); + let IMAP; let _POP3Helper; const startEmailIntercepter = _.debounce(Meteor.bindEnvironment(function() { - console.log('Starting Email Intercepter...'); + logger.debug('Starting Email Intercepter...'); if (settings.get('Direct_Reply_Enable') && settings.get('Direct_Reply_Protocol') && settings.get('Direct_Reply_Host') && settings.get('Direct_Reply_Port') && settings.get('Direct_Reply_Username') && settings.get('Direct_Reply_Password')) { if (settings.get('Direct_Reply_Protocol') === 'IMAP') { // stop already running IMAP instance if (IMAP && IMAP.isActive()) { - console.log('Disconnecting already running IMAP instance...'); + logger.debug('Disconnecting already running IMAP instance...'); IMAP.stop(Meteor.bindEnvironment(function() { - console.log('Starting new IMAP instance......'); + logger.debug('Starting new IMAP instance......'); IMAP = new IMAPIntercepter(); IMAP.start(); return true; })); } else if (POP3 && _POP3Helper && _POP3Helper.isActive()) { - console.log('Disconnecting already running POP instance...'); + logger.debug('Disconnecting already running POP instance...'); _POP3Helper.stop(Meteor.bindEnvironment(function() { - console.log('Starting new IMAP instance......'); + logger.debug('Starting new IMAP instance......'); IMAP = new IMAPIntercepter(); IMAP.start(); return true; })); } else { - console.log('Starting new IMAP instance......'); + logger.debug('Starting new IMAP instance......'); IMAP = new IMAPIntercepter(); IMAP.start(); return true; @@ -39,23 +42,23 @@ const startEmailIntercepter = _.debounce(Meteor.bindEnvironment(function() { } else if (settings.get('Direct_Reply_Protocol') === 'POP') { // stop already running POP instance if (POP3 && _POP3Helper && _POP3Helper.isActive()) { - console.log('Disconnecting already running POP instance...'); + logger.debug('Disconnecting already running POP instance...'); _POP3Helper.stop(Meteor.bindEnvironment(function() { - console.log('Starting new POP instance......'); + logger.debug('Starting new POP instance......'); _POP3Helper = new POP3Helper(); _POP3Helper.start(); return true; })); } else if (IMAP && IMAP.isActive()) { - console.log('Disconnecting already running IMAP instance...'); + logger.debug('Disconnecting already running IMAP instance...'); IMAP.stop(Meteor.bindEnvironment(function() { - console.log('Starting new POP instance......'); + logger.debug('Starting new POP instance......'); _POP3Helper = new POP3Helper(); _POP3Helper.start(); return true; })); } else { - console.log('Starting new POP instance......'); + logger.debug('Starting new POP instance......'); _POP3Helper = new POP3Helper(); _POP3Helper.start(); return true; diff --git a/app/lib/server/startup/settingsOnLoadSMTP.js b/app/lib/server/startup/settingsOnLoadSMTP.js index 4ad9b806933d..cb31e03e7541 100644 --- a/app/lib/server/startup/settingsOnLoadSMTP.js +++ b/app/lib/server/startup/settingsOnLoadSMTP.js @@ -1,10 +1,11 @@ import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; -import { settings } from '../../../settings'; +import { settings } from '../../../settings/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const buildMailURL = _.debounce(function() { - console.log('Updating process.env.MAIL_URL'); + SystemLogger.info('Updating process.env.MAIL_URL'); if (settings.get('SMTP_Host')) { process.env.MAIL_URL = `${ settings.get('SMTP_Protocol') }://`; diff --git a/app/livechat/imports/server/rest/facebook.js b/app/livechat/imports/server/rest/facebook.js index b4b8efa55034..cb9f19afc86c 100644 --- a/app/livechat/imports/server/rest/facebook.js +++ b/app/livechat/imports/server/rest/facebook.js @@ -90,7 +90,7 @@ API.v1.addRoute('livechat/facebook', { message: Livechat.sendMessage(sendMessage), }; } catch (e) { - console.error('Error using Facebook ->', e); + Livechat.logger.error('Error using Facebook ->', e); } }, }); diff --git a/app/livechat/imports/server/rest/sms.js b/app/livechat/imports/server/rest/sms.js index fe627ba6d817..de08af6d2344 100644 --- a/app/livechat/imports/server/rest/sms.js +++ b/app/livechat/imports/server/rest/sms.js @@ -132,7 +132,7 @@ API.v1.addRoute('livechat/sms-incoming/:service', { attachment.video_size = file.size; } } catch (e) { - console.error(`Attachment upload failed: ${ e.message }`); + Livechat.logger.error(`Attachment upload failed: ${ e.message }`); attachment = { fields: [{ title: 'User upload failed', diff --git a/app/livechat/server/hooks/RDStation.js b/app/livechat/server/hooks/RDStation.js index bc60b1c1c9ef..b15453995eda 100644 --- a/app/livechat/server/hooks/RDStation.js +++ b/app/livechat/server/hooks/RDStation.js @@ -3,6 +3,7 @@ import { HTTP } from 'meteor/http'; import { settings } from '../../../settings'; import { callbacks } from '../../../callbacks'; import { Livechat } from '../lib/Livechat'; +import { SystemLogger } from '../../../../server/lib/logger/system'; function sendToRDStation(room) { if (!settings.get('Livechat_RDStation_Token')) { @@ -50,7 +51,7 @@ function sendToRDStation(room) { try { HTTP.call('POST', 'https://www.rdstation.com.br/api/1.3/conversions', options); } catch (e) { - console.error('Error sending lead to RD Station ->', e); + SystemLogger.error('Error sending lead to RD Station ->', e); } return room; diff --git a/app/livechat/server/lib/Helper.js b/app/livechat/server/lib/Helper.js index d27556933abc..ed949f035ea0 100644 --- a/app/livechat/server/lib/Helper.js +++ b/app/livechat/server/lib/Helper.js @@ -196,7 +196,7 @@ export const parseAgentCustomFields = (customFields) => { return Object.keys(parseCustomFields) .filter((customFieldKey) => parseCustomFields[customFieldKey].sendToIntegrations === true); } catch (error) { - console.error(error); + Livechat.logger.error(error); return []; } }; diff --git a/app/livechat/server/lib/Livechat.js b/app/livechat/server/lib/Livechat.js index 108542221e4b..e6a9022421c3 100644 --- a/app/livechat/server/lib/Livechat.js +++ b/app/livechat/server/lib/Livechat.js @@ -41,18 +41,16 @@ import { Apps, AppEvents } from '../../../apps/server'; import { businessHourManager } from '../business-hour'; import notifications from '../../../notifications/server/lib/Notifications'; +const logger = new Logger('Livechat'); + const dnsResolveMx = Meteor.wrapAsync(dns.resolveMx); export const Livechat = { Analytics, historyMonitorType: 'url', - logger: new Logger('Livechat', { - sections: { - webhook: 'Webhook', - }, - }), - + logger, + webhookLogger: logger.section('Webhook'), findGuest(token) { return LivechatVisitors.getVisitorByToken(token, { @@ -713,7 +711,7 @@ export const Livechat = { this.saveTransferHistory(room, transferData); RoutingManager.unassignAgent(inquiry, departmentId); } catch (e) { - console.error(e); + this.logger.error(e); throw new Meteor.Error('error-returning-inquiry', 'Error returning inquiry to the queue', { method: 'livechat:returnRoomAsInquiry' }); } @@ -732,9 +730,9 @@ export const Livechat = { try { return HTTP.post(settings.get('Livechat_webhookUrl'), options); } catch (e) { - Livechat.logger.webhook.error(`Response error on ${ 11 - attempts } try ->`, e); + Livechat.webhookLogger.error(`Response error on ${ 11 - attempts } try ->`, e); // try 10 times after 10 seconds each - Livechat.logger.webhook.warn('Will try again in 10 seconds ...'); + Livechat.webhookLogger.warn('Will try again in 10 seconds ...'); setTimeout(Meteor.bindEnvironment(function() { Livechat.sendRequest(postData, callback, attempts--); }), 10000); diff --git a/app/livechat/server/lib/routing/External.js b/app/livechat/server/lib/routing/External.js index 4b104a9d2df0..5a72c1ef273f 100644 --- a/app/livechat/server/lib/routing/External.js +++ b/app/livechat/server/lib/routing/External.js @@ -4,6 +4,7 @@ import { HTTP } from 'meteor/http'; import { settings } from '../../../../settings/server'; import { RoutingManager } from '../RoutingManager'; import { Users } from '../../../../models/server'; +import { SystemLogger } from '../../../../../server/lib/logger/system'; class ExternalQueue { constructor() { @@ -45,7 +46,7 @@ class ExternalQueue { } } } catch (e) { - console.error('Error requesting agent from external queue.', e); + SystemLogger.error('Error requesting agent from external queue.', e); break; } } diff --git a/app/livechat/server/methods/facebook.js b/app/livechat/server/methods/facebook.js index 7d17161fe938..a6ef3b9aac94 100644 --- a/app/livechat/server/methods/facebook.js +++ b/app/livechat/server/methods/facebook.js @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { hasPermission } from '../../../authorization'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { settings } from '../../../settings'; import OmniChannel from '../lib/OmniChannel'; @@ -59,7 +60,7 @@ Meteor.methods({ throw new Meteor.Error('integration-error', e.response.data.error.message); } } - console.error('Error contacting omni.rocket.chat:', e); + SystemLogger.error('Error contacting omni.rocket.chat:', e); throw new Meteor.Error('integration-error', e.error); } }, diff --git a/app/livechat/server/methods/getAgentOverviewData.js b/app/livechat/server/methods/getAgentOverviewData.js index f6cc509f1441..d60d36957530 100644 --- a/app/livechat/server/methods/getAgentOverviewData.js +++ b/app/livechat/server/methods/getAgentOverviewData.js @@ -14,7 +14,7 @@ Meteor.methods({ } if (!(options.chartOptions && options.chartOptions.name)) { - console.log('Incorrect analytics options'); + Livechat.logger.warn('Incorrect analytics options'); return; } diff --git a/app/livechat/server/methods/getAnalyticsChartData.js b/app/livechat/server/methods/getAnalyticsChartData.js index 42b92ac31a4b..caa86c650899 100644 --- a/app/livechat/server/methods/getAnalyticsChartData.js +++ b/app/livechat/server/methods/getAnalyticsChartData.js @@ -14,7 +14,7 @@ Meteor.methods({ } if (!(options.chartOptions && options.chartOptions.name)) { - console.log('Incorrect chart options'); + Livechat.logger.warn('Incorrect chart options'); return; } diff --git a/app/livechat/server/methods/getAnalyticsOverviewData.js b/app/livechat/server/methods/getAnalyticsOverviewData.js index 741e26ccee53..30fdec7835d8 100644 --- a/app/livechat/server/methods/getAnalyticsOverviewData.js +++ b/app/livechat/server/methods/getAnalyticsOverviewData.js @@ -15,7 +15,7 @@ Meteor.methods({ } if (!(options.analyticsOptions && options.analyticsOptions.name)) { - console.error('Incorrect analytics options'); + Livechat.logger.error('Incorrect analytics options'); return; } diff --git a/app/livechat/server/methods/webhookTest.js b/app/livechat/server/methods/webhookTest.js index b834ec246b40..bc5b32fd75a0 100644 --- a/app/livechat/server/methods/webhookTest.js +++ b/app/livechat/server/methods/webhookTest.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { HTTP } from 'meteor/http'; import { settings } from '../../../settings/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const postCatchError = function(url, options) { try { @@ -71,7 +72,7 @@ Meteor.methods({ const response = postCatchError(settings.get('Livechat_webhookUrl'), options); - console.log('response ->', response); + SystemLogger.debug({ response }); if (response && response.statusCode && response.statusCode === 200) { return true; diff --git a/app/logger/server/index.js b/app/logger/server/index.js index 06fa09708dbe..f535468e5d9f 100644 --- a/app/logger/server/index.js +++ b/app/logger/server/index.js @@ -1,8 +1,7 @@ -import './streamer.js'; -import { LoggerManager, Logger, SystemLogger } from './server'; +import { Logger } from '../../../server/lib/logger/Logger'; +import './streamer'; +// TODO there are imports pointing to this file still, ideally we should point everything to "/server/lib/logger/Logger" and remove this file export { - LoggerManager, Logger, - SystemLogger, }; diff --git a/app/logger/server/server.js b/app/logger/server/server.js deleted file mode 100644 index bce22758c551..000000000000 --- a/app/logger/server/server.js +++ /dev/null @@ -1,321 +0,0 @@ -import { EventEmitter } from 'events'; - -import _ from 'underscore'; -import s from 'underscore.string'; - -export const LoggerManager = new class extends EventEmitter { - constructor() { - super(); - this.enabled = false; - this.loggers = {}; - this.queue = []; - this.showPackage = false; - this.showFileAndLine = false; - this.logLevel = 0; - } - - register(logger) { - // eslint-disable-next-line no-use-before-define - if (!(logger instanceof Logger)) { - return; - } - this.loggers[logger.name] = logger; - this.emit('register', logger); - } - - addToQueue(logger, args) { - this.queue.push({ - logger, args, - }); - } - - dispatchQueue() { - _.each(this.queue, (item) => item.logger._log.apply(item.logger, item.args)); - this.clearQueue(); - } - - clearQueue() { - this.queue = []; - } - - disable() { - this.enabled = false; - } - - enable(dispatchQueue = false) { - this.enabled = true; - return dispatchQueue === true ? this.dispatchQueue() : this.clearQueue(); - } -}(); - -const defaultTypes = { - debug: { - name: 'debug', - color: 'blue', - level: 2, - }, - log: { - name: 'info', - color: 'blue', - level: 1, - }, - info: { - name: 'info', - color: 'blue', - level: 1, - }, - success: { - name: 'info', - color: 'green', - level: 1, - }, - warn: { - name: 'warn', - color: 'magenta', - level: 1, - }, - error: { - name: 'error', - color: 'red', - level: 0, - }, - deprecation: { - name: 'warn', - color: 'magenta', - level: 0, - }, -}; - -export class Logger { - constructor(name, config = {}) { - const self = this; - this.name = name; - - this.config = Object.assign({}, config); - if (LoggerManager.loggers && LoggerManager.loggers[this.name] != null) { - LoggerManager.loggers[this.name].warn('Duplicated instance'); - return LoggerManager.loggers[this.name]; - } - _.each(defaultTypes, (typeConfig, type) => { - this[type] = function(...args) { - return self._log.call(self, { - section: this.__section, - type, - level: typeConfig.level, - method: typeConfig.name, - arguments: args, - }); - }; - - self[`${ type }_box`] = function(...args) { - return self._log.call(self, { - section: this.__section, - type, - box: true, - level: typeConfig.level, - method: typeConfig.name, - arguments: args, - }); - }; - }); - if (this.config.methods) { - _.each(this.config.methods, (typeConfig, method) => { - if (this[method] != null) { - self.warn(`Method ${ method } already exists`); - } - if (defaultTypes[typeConfig.type] == null) { - self.warn(`Method type ${ typeConfig.type } does not exist`); - } - this[method] = function(...args) { - return self._log.call(self, { - section: this.__section, - type: typeConfig.type, - level: typeConfig.level != null ? typeConfig.level : defaultTypes[typeConfig.type] && defaultTypes[typeConfig.type].level, - method, - arguments: args, - }); - }; - this[`${ method }_box`] = function(...args) { - return self._log.call(self, { - section: this.__section, - type: typeConfig.type, - box: true, - level: typeConfig.level != null ? typeConfig.level : defaultTypes[typeConfig.type] && defaultTypes[typeConfig.type].level, - method, - arguments: args, - }); - }; - }); - } - if (this.config.sections) { - _.each(this.config.sections, (name, section) => { - this[section] = {}; - _.each(defaultTypes, (typeConfig, type) => { - self[section][type] = (...args) => this[type].apply({ __section: name }, args); - self[section][`${ type }_box`] = (...args) => this[`${ type }_box`].apply({ __section: name }, args); - }); - _.each(this.config.methods, (typeConfig, method) => { - self[section][method] = (...args) => self[method].apply({ __section: name }, args); - self[section][`${ method }_box`] = (...args) => self[`${ method }_box`].apply({ __section: name }, args); - }); - }); - } - - LoggerManager.register(this); - } - - getPrefix(options) { - let prefix = `${ this.name } ➔ ${ options.method }`; - if (options.section) { - prefix = `${ this.name } ➔ ${ options.section }.${ options.method }`; - } - const details = this._getCallerDetails(); - const detailParts = []; - if (details.package && (LoggerManager.showPackage === true || options.type === 'error')) { - detailParts.push(details.package); - } - if (LoggerManager.showFileAndLine === true || options.type === 'error') { - if ((details.file != null) && (details.line != null)) { - detailParts.push(`${ details.file }:${ details.line }`); - } else { - if (details.file != null) { - detailParts.push(details.file); - } - if (details.line != null) { - detailParts.push(details.line); - } - } - } - if (defaultTypes[options.type]) { - // format the message to a colored message - prefix = prefix[defaultTypes[options.type].color]; - } - if (detailParts.length > 0) { - prefix = `${ detailParts.join(' ') } ${ prefix }`; - } - return prefix; - } - - _getCallerDetails() { - const getStack = () => { - // We do NOT use Error.prepareStackTrace here (a V8 extension that gets us a - // core-parsed stack) since it's impossible to compose it with the use of - // Error.prepareStackTrace used on the server for source maps. - const { stack } = new Error(); - return stack; - }; - const stack = getStack(); - if (!stack) { - return {}; - } - const lines = stack.split('\n').splice(1); - // looking for the first line outside the logging package (or an - // eval if we find that first) - let line = lines[0]; - for (let index = 0, len = lines.length; index < len; index++, line = lines[index]) { - if (line.match(/^\s*at eval \(eval/)) { - return { file: 'eval' }; - } - - if (!line.match(/packages\/rocketchat_logger(?:\/|\.js)/)) { - break; - } - } - - const details = {}; - // The format for FF is 'functionName@filePath:lineNumber' - // The format for V8 is 'functionName (packages/logging/logging.js:81)' or - // 'packages/logging/logging.js:81' - const match = /(?:[@(]| at )([^(]+?):([0-9:]+)(?:\)|$)/.exec(line); - if (!match) { - return details; - } - details.line = match[2].split(':')[0]; - // Possible format: https://foo.bar.com/scripts/file.js?random=foobar - // XXX: if you can write the following in better way, please do it - // XXX: what about evals? - details.file = match[1].split('/').slice(-1)[0].split('?')[0]; - const packageMatch = match[1].match(/packages\/([^\.\/]+)(?:\/|\.)/); - if (packageMatch) { - details.package = packageMatch[1]; - } - return details; - } - - makeABox(message, title) { - if (!_.isArray(message)) { - message = message.split('\n'); - } - let len = 0; - - len = Math.max.apply(null, message.map((line) => line.length)); - - const topLine = `+--${ s.pad('', len, '-') }--+`; - const separator = `| ${ s.pad('', len, '') } |`; - let lines = []; - - lines.push(topLine); - if (title) { - lines.push(`| ${ s.lrpad(title, len) } |`); - lines.push(topLine); - } - lines.push(separator); - - lines = [...lines, ...message.map((line) => `| ${ s.rpad(line, len) } |`)]; - - lines.push(separator); - lines.push(topLine); - return lines; - } - - _log(options, ...args) { - if (LoggerManager.enabled === false) { - LoggerManager.addToQueue(this, [options, ...args]); - return; - } - if (options.level == null) { - options.level = 1; - } - - if (LoggerManager.logLevel < options.level) { - return; - } - - // Deferred logging - if (typeof options.arguments[0] === 'function') { - options.arguments[0] = options.arguments[0](); - } - - const prefix = this.getPrefix(options); - - if (options.box === true && _.isString(options.arguments[0])) { - let color = undefined; - if (defaultTypes[options.type]) { - color = defaultTypes[options.type].color; - } - - const box = this.makeABox(options.arguments[0], options.arguments[1]); - let subPrefix = '➔'; - if (color) { - subPrefix = subPrefix[color]; - } - - console.log(subPrefix, prefix); - box.forEach((line) => { - console.log(subPrefix, color ? line[color] : line); - }); - } else { - options.arguments.unshift(prefix); - console.log.apply(console, options.arguments); - } - } -} - -export const SystemLogger = new Logger('System', { - methods: { - startup: { - type: 'success', - level: 0, - }, - }, -}); diff --git a/app/logger/server/streamer.js b/app/logger/server/streamer.js index 3bff9032aafb..7e7294439310 100644 --- a/app/logger/server/streamer.js +++ b/app/logger/server/streamer.js @@ -1,14 +1,13 @@ import { EventEmitter } from 'events'; import { Meteor } from 'meteor/meteor'; -import { Random } from 'meteor/random'; import { EJSON } from 'meteor/ejson'; import { Log } from 'meteor/logging'; -import { settings } from '../../settings'; +import { settings } from '../../settings/server'; import notifications from '../../notifications/server/lib/Notifications'; -export const processString = function(string, date) { +const processString = function(string, date) { let obj; try { if (string[0] === '{') { @@ -26,31 +25,35 @@ export const processString = function(string, date) { } }; -export const StdOut = new class extends EventEmitter { - constructor() { - super(); - const { write } = process.stdout; - this.queue = []; - process.stdout.write = (...args) => { - write.apply(process.stdout, args); - const date = new Date(); - const string = processString(args[0], date); - const item = { - id: Random.id(), - string, - ts: date, - }; - this.queue.push(item); +export const StdOut = new EventEmitter(); + +const { write } = process.stdout; + +const queue = []; + +const maxInt = 2147483647; +let queueSize = 0; - const limit = settings.get('Log_View_Limit') || 1000; - if (limit && this.queue.length > limit) { - this.queue.shift(); - } +process.stdout.write = (...args) => { + write.apply(process.stdout, args); + const date = new Date(); + const string = processString(args[0], date); + const item = { + id: `logid-${ queueSize }`, + string, + ts: date, + }; + queue.push(item); + + queueSize = (queueSize + 1) & maxInt; - this.emit('write', string, item); - }; + const limit = settings.get('Log_View_Limit') || 1000; + if (queueSize > limit) { + queue.shift(); } -}(); + + StdOut.emit('write', string, item); +}; Meteor.startup(() => { const handler = (string, item) => { diff --git a/app/mail-messages/server/functions/sendMail.js b/app/mail-messages/server/functions/sendMail.js index 65dc7687331b..6b33a1dc2b0f 100644 --- a/app/mail-messages/server/functions/sendMail.js +++ b/app/mail-messages/server/functions/sendMail.js @@ -3,7 +3,8 @@ import { EJSON } from 'meteor/ejson'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { escapeHTML } from '@rocket.chat/string-helpers'; -import { placeholders } from '../../../utils'; +import { placeholders } from '../../../utils/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import * as Mailer from '../../../mailer'; export const sendMail = function(from, subject, body, dryrun, query) { @@ -33,7 +34,7 @@ export const sendMail = function(from, subject, body, dryrun, query) { email, }); - console.log(`Sending email to ${ email }`); + SystemLogger.debug(`Sending email to ${ email }`); return Mailer.send({ to: email, from, @@ -54,7 +55,7 @@ export const sendMail = function(from, subject, body, dryrun, query) { name: escapeHTML(user.name), email: escapeHTML(email), }); - console.log(`Sending email to ${ email }`); + SystemLogger.debug(`Sending email to ${ email }`); return Mailer.send({ to: email, from, diff --git a/app/mail-messages/server/functions/unsubscribe.js b/app/mail-messages/server/functions/unsubscribe.js index 9d892acb0c50..c06c568ff822 100644 --- a/app/mail-messages/server/functions/unsubscribe.js +++ b/app/mail-messages/server/functions/unsubscribe.js @@ -1,8 +1,13 @@ -import { Users } from '../../../models'; +import { Users } from '../../../models/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; export const unsubscribe = function(_id, createdAt) { if (_id && createdAt) { - return Users.rocketMailUnsubscribe(_id, createdAt) === 1; + const affectedRows = Users.rocketMailUnsubscribe(_id, createdAt) === 1; + + SystemLogger.debug('[Mailer:Unsubscribe]', _id, createdAt, new Date(parseInt(createdAt)), affectedRows); + + return affectedRows; } return false; }; diff --git a/app/message-mark-as-unread/server/logger.js b/app/message-mark-as-unread/server/logger.js index 1327ecda6e8c..4752c07a23dc 100644 --- a/app/message-mark-as-unread/server/logger.js +++ b/app/message-mark-as-unread/server/logger.js @@ -1,9 +1,4 @@ import { Logger } from '../../logger'; -const logger = new Logger('MessageMarkAsUnread', { - sections: { - connection: 'Connection', - events: 'Events', - }, -}); +const logger = new Logger('MessageMarkAsUnread'); export default logger; diff --git a/app/message-mark-as-unread/server/unreadMessages.js b/app/message-mark-as-unread/server/unreadMessages.js index da31e72a35af..c10a3fc1ae5c 100644 --- a/app/message-mark-as-unread/server/unreadMessages.js +++ b/app/message-mark-as-unread/server/unreadMessages.js @@ -48,9 +48,9 @@ Meteor.methods({ } const lastSeen = Subscriptions.findOneByRoomIdAndUserId(originalMessage.rid, userId).ls; if (firstUnreadMessage.ts >= lastSeen) { - return logger.connection.debug('Provided message is already marked as unread'); + return logger.debug('Provided message is already marked as unread'); } - logger.connection.debug(`Updating unread message of ${ originalMessage.ts } as the first unread`); + logger.debug(`Updating unread message of ${ originalMessage.ts } as the first unread`); return Subscriptions.setAsUnreadByRoomIdAndUserId(originalMessage.rid, userId, originalMessage.ts); }, }); diff --git a/app/meteor-accounts-saml/server/lib/SAML.ts b/app/meteor-accounts-saml/server/lib/SAML.ts index ca876193ac37..9327aa44ac7f 100644 --- a/app/meteor-accounts-saml/server/lib/SAML.ts +++ b/app/meteor-accounts-saml/server/lib/SAML.ts @@ -17,6 +17,7 @@ import { IServiceProviderOptions } from '../definition/IServiceProviderOptions'; import { ISAMLAction } from '../definition/ISAMLAction'; import { ISAMLUser } from '../definition/ISAMLUser'; import { SAMLUtils } from './Utils'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const showErrorMessage = function(res: ServerResponse, err: string): void { res.writeHead(200, { @@ -240,7 +241,7 @@ export class SAML { const serviceProvider = new SAMLServiceProvider(service); serviceProvider.validateLogoutRequest(req.query.SAMLRequest, (err, result) => { if (err) { - console.error(err); + SystemLogger.error({ err }); throw new Meteor.Error('Unable to Validate Logout Request'); } @@ -293,14 +294,14 @@ export class SAML { serviceProvider.logoutResponseToUrl(response, (err, url) => { if (err) { - console.error(err); + SystemLogger.error({ err }); return redirect(); } redirect(url); }); } catch (e) { - console.error(e); + SystemLogger.error(e); redirect(); } }).run(); @@ -472,7 +473,7 @@ export class SAML { } } } catch (err) { - console.error(err); + SystemLogger.error(err); } } } diff --git a/app/meteor-accounts-saml/server/lib/Utils.ts b/app/meteor-accounts-saml/server/lib/Utils.ts index 20671c07a415..aa4156c8c567 100644 --- a/app/meteor-accounts-saml/server/lib/Utils.ts +++ b/app/meteor-accounts-saml/server/lib/Utils.ts @@ -141,7 +141,7 @@ export class SAMLUtils { public static log(...args: Array): void { if (debug && logger) { - logger.info(...args); + logger.debug(...args); } } diff --git a/app/meteor-accounts-saml/server/lib/parsers/LogoutRequest.ts b/app/meteor-accounts-saml/server/lib/parsers/LogoutRequest.ts index 7f6d85181ef0..67da8570c493 100644 --- a/app/meteor-accounts-saml/server/lib/parsers/LogoutRequest.ts +++ b/app/meteor-accounts-saml/server/lib/parsers/LogoutRequest.ts @@ -38,7 +38,7 @@ export class LogoutRequestParser { return callback(null, { idpSession, nameID, id }); } catch (e) { - console.error(e); + SAMLUtils.error(e); SAMLUtils.log(`Caught error: ${ e }`); const msg = doc.getElementsByTagNameNS('urn:oasis:names:tc:SAML:2.0:protocol', 'StatusMessage'); diff --git a/app/meteor-accounts-saml/server/lib/parsers/Response.ts b/app/meteor-accounts-saml/server/lib/parsers/Response.ts index 1a813b3f0a75..4a21f29cf88f 100644 --- a/app/meteor-accounts-saml/server/lib/parsers/Response.ts +++ b/app/meteor-accounts-saml/server/lib/parsers/Response.ts @@ -140,7 +140,7 @@ export class ResponseParser { } } - SAMLUtils.log(`NameID: ${ JSON.stringify(profile) }`); + SAMLUtils.log({ msg: 'NameID', profile }); return callback(null, profile, false); } @@ -178,7 +178,7 @@ export class ResponseParser { const encData = encAssertion.getElementsByTagNameNS('*', 'EncryptedData')[0]; xmlenc.decrypt(encData, options, function(err: Error, result: string) { if (err) { - console.error(err); + SAMLUtils.error(err); } const document = new xmldom.DOMParser().parseFromString(result, 'text/xml'); @@ -320,7 +320,7 @@ export class ResponseParser { const options = { key: this.serviceProviderOptions.privateKey }; xmlenc.decrypt(encSubject.getElementsByTagNameNS('*', 'EncryptedData')[0], options, function(err: Error, result: string) { if (err) { - console.error(err); + SAMLUtils.error(err); } subject = new xmldom.DOMParser().parseFromString(result, 'text/xml'); }); diff --git a/app/meteor-accounts-saml/server/lib/settings.ts b/app/meteor-accounts-saml/server/lib/settings.ts index b18b509c772d..b71cc6551af8 100644 --- a/app/meteor-accounts-saml/server/lib/settings.ts +++ b/app/meteor-accounts-saml/server/lib/settings.ts @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { ServiceConfiguration } from 'meteor/service-configuration'; import { settings } from '../../../settings/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { SettingComposedValue } from '../../../settings/lib/settings'; import { IServiceProviderOptions } from '../definition/IServiceProviderOptions'; import { SAMLUtils } from './Utils'; @@ -131,7 +132,7 @@ export const loadSamlServiceProviders = function(): void { }; export const addSamlService = function(name: string): void { - console.log(`Adding ${ name } is deprecated`); + SystemLogger.warn(`Adding ${ name } is deprecated`); }; export const addSettings = function(name: string): void { diff --git a/app/meteor-accounts-saml/server/listener.ts b/app/meteor-accounts-saml/server/listener.ts index 4edae1cb301a..d4352315459b 100644 --- a/app/meteor-accounts-saml/server/listener.ts +++ b/app/meteor-accounts-saml/server/listener.ts @@ -6,6 +6,7 @@ import { RoutePolicy } from 'meteor/routepolicy'; import bodyParser from 'body-parser'; import fiber from 'fibers'; +import { SystemLogger } from '../../../server/lib/logger/system'; import { SAML } from './lib/SAML'; import { SAMLUtils } from './lib/Utils'; import { ISAMLAction } from './definition/ISAMLAction'; @@ -54,14 +55,14 @@ const middleware = function(req: IIncomingMessage, res: ServerResponse, next: (e const service = SAMLUtils.getServiceProviderOptions(samlObject.serviceName); if (!service) { - console.error(`${ samlObject.serviceName } service provider not found`); + SystemLogger.error(`${ samlObject.serviceName } service provider not found`); throw new Error('SAML Service Provider not found.'); } SAML.processRequest(req, res, service, samlObject); } catch (err) { // @ToDo: Ideally we should send some error message to the client, but there's no way to do it on a redirect right now. - console.log(err); + SystemLogger.error(err); const url = Meteor.absoluteUrl('home'); res.writeHead(302, { diff --git a/app/meteor-accounts-saml/server/loginHandler.ts b/app/meteor-accounts-saml/server/loginHandler.ts index 84beec3091aa..64680efbfb64 100644 --- a/app/meteor-accounts-saml/server/loginHandler.ts +++ b/app/meteor-accounts-saml/server/loginHandler.ts @@ -3,6 +3,7 @@ import { Accounts } from 'meteor/accounts-base'; import { SAMLUtils } from './lib/Utils'; import { SAML } from './lib/SAML'; +import { SystemLogger } from '../../../server/lib/logger/system'; const makeError = (message: string): Record => ({ type: 'saml', @@ -16,7 +17,7 @@ Accounts.registerLoginHandler('saml', function(loginRequest) { } const loginResult = SAML.retrieveCredential(loginRequest.credentialToken); - SAMLUtils.log(`RESULT :${ JSON.stringify(loginResult) }`); + SAMLUtils.log({ msg: 'RESULT', loginResult }); if (!loginResult) { return makeError('No matching login attempt found'); @@ -31,7 +32,7 @@ Accounts.registerLoginHandler('saml', function(loginRequest) { return SAML.insertOrUpdateSAMLUser(userObject); } catch (error) { - console.error(error); + SystemLogger.error(error); return makeError(error.toString()); } }); diff --git a/app/meteor-accounts-saml/server/methods/samlLogout.ts b/app/meteor-accounts-saml/server/methods/samlLogout.ts index ceedc2de0cb1..9ee693123a9a 100644 --- a/app/meteor-accounts-saml/server/methods/samlLogout.ts +++ b/app/meteor-accounts-saml/server/methods/samlLogout.ts @@ -32,7 +32,7 @@ Meteor.methods({ } const providerConfig = getSamlServiceProviderOptions(provider); - SAMLUtils.log(`Logout request from ${ JSON.stringify(providerConfig) }`); + SAMLUtils.log({ msg: 'Logout request', providerConfig }); // This query should respect upcoming array of SAML logins const user = Users.getSAMLByIdAndSAMLProvider(Meteor.userId(), provider); if (!user || !user.services || !user.services.saml) { @@ -40,7 +40,7 @@ Meteor.methods({ } const { nameID, idpSession } = user.services.saml; - SAMLUtils.log(`NameID for user ${ Meteor.userId() } found: ${ JSON.stringify(nameID) }`); + SAMLUtils.log({ msg: `NameID for user ${ Meteor.userId() } found`, nameID }); const _saml = new SAMLServiceProvider(providerConfig); diff --git a/app/meteor-accounts-saml/server/startup.ts b/app/meteor-accounts-saml/server/startup.ts index d76cf007d418..a3067c26dfd3 100644 --- a/app/meteor-accounts-saml/server/startup.ts +++ b/app/meteor-accounts-saml/server/startup.ts @@ -8,7 +8,7 @@ import { SAMLUtils } from './lib/Utils'; settings.addGroup('SAML'); -export const logger = new Logger('steffo:meteor-accounts-saml', {}); +export const logger = new Logger('steffo:meteor-accounts-saml'); SAMLUtils.setLoggerInstance(logger); const updateServices = _.debounce(Meteor.bindEnvironment(() => { diff --git a/app/metrics/server/lib/collectMetrics.js b/app/metrics/server/lib/collectMetrics.js index 66a24da4df91..be97d5b98e87 100644 --- a/app/metrics/server/lib/collectMetrics.js +++ b/app/metrics/server/lib/collectMetrics.js @@ -8,9 +8,10 @@ import { Meteor } from 'meteor/meteor'; import { Facts } from 'meteor/facts-base'; import { Info, getOplogInfo } from '../../../utils/server'; -import { Migrations } from '../../../migrations'; -import { settings } from '../../../settings'; -import { Statistics } from '../../../models'; +import { Migrations } from '../../../migrations/server'; +import { settings } from '../../../settings/server'; +import { Statistics } from '../../../models/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; import { metrics } from './metrics'; import { getAppsStatistics } from '../../../statistics/server/lib/getAppsStatistics'; @@ -136,7 +137,7 @@ const updatePrometheusConfig = async () => { if (!is.enabled) { if (was.enabled) { - console.log('Disabling Prometheus'); + SystemLogger.info('Disabling Prometheus'); server.close(); Meteor.clearInterval(timer); } @@ -144,7 +145,7 @@ const updatePrometheusConfig = async () => { return; } - console.log('Configuring Prometheus', is); + SystemLogger.debug({ msg: 'Configuring Prometheus', is }); if (!was.enabled) { server.listen({ @@ -174,7 +175,7 @@ const updatePrometheusConfig = async () => { gcStats()(); } } catch (error) { - console.error(error); + SystemLogger.error(error); } Object.assign(was, is); diff --git a/app/migrations/server/migrations.js b/app/migrations/server/migrations.js index c7d25a94dad6..dbfebfeaa531 100644 --- a/app/migrations/server/migrations.js +++ b/app/migrations/server/migrations.js @@ -1,13 +1,13 @@ /* eslint no-use-before-define:0 */ import { Meteor } from 'meteor/meteor'; -import { Match, check } from 'meteor/check'; +import { check } from 'meteor/check'; import { Mongo } from 'meteor/mongo'; -import { Log } from 'meteor/logging'; import _ from 'underscore'; import s from 'underscore.string'; import moment from 'moment'; -import { Info } from '../../utils'; +import { Info } from '../../utils/server'; +import { Logger } from '../../logger/server'; /* Adds migration capabilities. Migrations are defined like: @@ -87,50 +87,7 @@ function makeABox(message, color = 'red') { return `\n${ topLine }\n${ separator }\n${ text }\n${ separator }\n${ bottomLine }\n`; } -/* - Logger factory function. Takes a prefix string and options object - and uses an injected `logger` if provided, else falls back to - Meteor's `Log` package. - Will send a log object to the injected logger, on the following form: - message: String - level: String (info, warn, error, debug) - tag: 'Migrations' -*/ -function createLogger(prefix) { - check(prefix, String); - - // Return noop if logging is disabled. - if (Migrations.options.log === false) { - return function() {}; - } - - return function(level, message) { - check(level, Match.OneOf('info', 'error', 'warn', 'debug')); - check(message, Match.OneOf(String, [String])); - - const logger = Migrations.options && Migrations.options.logger; - - if (logger && _.isFunction(logger)) { - logger({ - level, - message, - tag: prefix, - }); - } else { - Log[level]({ - message: `${ prefix }: ${ message }`, - }); - } - }; -} - -// collection holding the control record - -const log = createLogger('Migrations'); - -['info', 'warn', 'error', 'debug'].forEach(function(level) { - log[level] = _.partial(log, level); -}); +const log = new Logger('Migrations'); // if (process.env.MIGRATE) // Migrations.migrateTo(process.env.MIGRATE); @@ -190,7 +147,7 @@ Migrations.migrateTo = function(command) { } else { willRetry = ''; } - console.log(`Not migrating, control is locked. Attempt ${ attempts }/${ maxAttempts }.${ willRetry }`.yellow); + log.warn(`Not migrating, control is locked. Attempt ${ attempts }/${ maxAttempts }.${ willRetry }`.yellow); } } if (!migrated) { @@ -275,7 +232,7 @@ Migrations._migrateTo = function(version, rerun) { try { migration[direction](migration); } catch (e) { - console.log(makeABox([ + console.error(makeABox([ 'ERROR! SERVER STOPPED', '', 'Your database migration failed:', diff --git a/app/models/server/models/Rooms.js b/app/models/server/models/Rooms.js index 05751f59cae5..d884208317fc 100644 --- a/app/models/server/models/Rooms.js +++ b/app/models/server/models/Rooms.js @@ -334,6 +334,7 @@ export class Rooms extends Base { let channelName = s.trim(name); try { + // TODO evaluate if this function call should be here channelName = getValidRoomName(channelName, null, { allowDuplicates: true }); } catch (e) { console.error(e); diff --git a/app/models/server/models/Users.js b/app/models/server/models/Users.js index 63b2c4278e97..c760c4d7172a 100644 --- a/app/models/server/models/Users.js +++ b/app/models/server/models/Users.js @@ -354,7 +354,6 @@ export class Users extends Base { }, }; const affectedRows = this.update(query, update); - console.log('[Mailer:Unsubscribe]', _id, createdAt, new Date(parseInt(createdAt)), affectedRows); return affectedRows; } diff --git a/app/models/server/models/_BaseDb.js b/app/models/server/models/_BaseDb.js index 46a285b53560..6c9473c81fb8 100644 --- a/app/models/server/models/_BaseDb.js +++ b/app/models/server/models/_BaseDb.js @@ -7,6 +7,7 @@ import _ from 'underscore'; import { setUpdatedAt } from '../lib/setUpdatedAt'; import { metrics } from '../../../metrics/server/lib/metrics'; import { getOplogHandle } from './_oplogHandle'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const baseName = 'rocketchat_'; @@ -20,7 +21,7 @@ try { trash._ensureIndex({ rid: 1, __collection__: 1, _deletedAt: 1 }); } catch (e) { - console.log(e); + SystemLogger.error(e); } const actions = { diff --git a/app/nextcloud/server/addWebdavServer.js b/app/nextcloud/server/addWebdavServer.js index fa331312705f..89622e54fd79 100644 --- a/app/nextcloud/server/addWebdavServer.js +++ b/app/nextcloud/server/addWebdavServer.js @@ -1,7 +1,8 @@ import { Meteor } from 'meteor/meteor'; -import { callbacks } from '../../callbacks'; -import { settings } from '../../settings'; +import { callbacks } from '../../callbacks/server'; +import { settings } from '../../settings/server'; +import { SystemLogger } from '../../../server/lib/logger/system'; Meteor.startup(() => { settings.get('Webdav_Integration_Enabled', (key, value) => { @@ -25,7 +26,7 @@ Meteor.startup(() => { try { Meteor.runAsUser(user._id, () => Meteor.call('addWebdavAccountByToken', data)); } catch (error) { - console.log(error); + SystemLogger.error(error); } }, callbacks.priority.MEDIUM, 'add-webdav-server'); } diff --git a/app/notification-queue/server/NotificationQueue.ts b/app/notification-queue/server/NotificationQueue.ts index 42f05827b919..d16da1cc71ee 100644 --- a/app/notification-queue/server/NotificationQueue.ts +++ b/app/notification-queue/server/NotificationQueue.ts @@ -5,6 +5,7 @@ import { NotificationQueue, Users } from '../../models/server/raw'; import { sendEmailFromData } from '../../lib/server/functions/notifications/email'; import { PushNotification } from '../../push-notifications/server'; import { IUser } from '../../../definition/IUser'; +import { SystemLogger } from '../../../server/lib/logger/system'; const { NOTIFICATIONS_WORKER_TIMEOUT = 2000, @@ -45,7 +46,7 @@ class NotificationClass { try { this.worker(); } catch (e) { - console.error('Error sending notification', e); + SystemLogger.error('Error sending notification', e); this.executeWorkerLater(); } }, this.cyclePause); @@ -81,7 +82,7 @@ class NotificationClass { NotificationQueue.removeById(notification._id); } catch (e) { - console.error(e); + SystemLogger.error(e); await NotificationQueue.setErrorById(notification._id, e.message); } diff --git a/app/oembed/server/providers.js b/app/oembed/server/providers.js index f6ba54a3d3ba..09415153a64b 100644 --- a/app/oembed/server/providers.js +++ b/app/oembed/server/providers.js @@ -4,7 +4,8 @@ import QueryString from 'querystring'; import { camelCase } from 'change-case'; import _ from 'underscore'; -import { callbacks } from '../../callbacks'; +import { callbacks } from '../../callbacks/server'; +import { SystemLogger } from '../../../server/lib/logger/system'; class Providers { constructor() { @@ -146,7 +147,7 @@ callbacks.add('oembed:afterParseContent', function(data) { } }); } catch (error) { - console.log(error); + SystemLogger.error(error); } return data; }, callbacks.priority.MEDIUM, 'oembed-providers-after'); diff --git a/app/oembed/server/server.js b/app/oembed/server/server.js index 34aa1a8eee1a..b859b4ed80de 100644 --- a/app/oembed/server/server.js +++ b/app/oembed/server/server.js @@ -14,6 +14,7 @@ import { OEmbedCache, Messages } from '../../models'; import { callbacks } from '../../callbacks'; import { settings } from '../../settings'; import { isURL } from '../../utils/lib/isURL'; +import { SystemLogger } from '../../../server/lib/logger/system'; const request = HTTPInternals.NpmModules.request.module; const OEmbed = {}; @@ -224,7 +225,7 @@ OEmbed.getUrlMetaWithCache = function(url, withFragment) { try { OEmbedCache.createWithIdAndData(url, data); } catch (_error) { - console.error('OEmbed duplicated record', url); + SystemLogger.error('OEmbed duplicated record', url); } return data; } diff --git a/app/push/server/apn.js b/app/push/server/apn.js index 693f8dcc0529..d84846fd592e 100644 --- a/app/push/server/apn.js +++ b/app/push/server/apn.js @@ -70,7 +70,7 @@ export const initAPN = ({ options, absoluteUrl }) => { // Give the user warnings about development settings if (options.apn.development) { // This flag is normally set by the configuration file - console.warn('WARNING: Push APN is using development key and certificate'); + logger.warn('WARNING: Push APN is using development key and certificate'); } else if (options.apn.gateway) { // We check the apn gateway i the options, we could risk shipping // server into production while using the production configuration. @@ -83,39 +83,39 @@ export const initAPN = ({ options, absoluteUrl }) => { if (options.apn.gateway === 'gateway.sandbox.push.apple.com') { // Using the development sandbox - console.warn('WARNING: Push APN is in development mode'); + logger.warn('WARNING: Push APN is in development mode'); } else if (options.apn.gateway === 'gateway.push.apple.com') { // In production - but warn if we are running on localhost if (/http:\/\/localhost/.test(absoluteUrl)) { - console.warn('WARNING: Push APN is configured to production mode - but server is running from localhost'); + logger.warn('WARNING: Push APN is configured to production mode - but server is running from localhost'); } } else { // Warn about gateways we dont know about - console.warn(`WARNING: Push APN unknown gateway "${ options.apn.gateway }"`); + logger.warn(`WARNING: Push APN unknown gateway "${ options.apn.gateway }"`); } } else if (options.apn.production) { if (/http:\/\/localhost/.test(absoluteUrl)) { - console.warn('WARNING: Push APN is configured to production mode - but server is running from localhost'); + logger.warn('WARNING: Push APN is configured to production mode - but server is running from localhost'); } } else { - console.warn('WARNING: Push APN is in development mode'); + logger.warn('WARNING: Push APN is in development mode'); } // Check certificate data if (!options.apn.cert || !options.apn.cert.length) { - console.error('ERROR: Push server could not find cert'); + logger.error('ERROR: Push server could not find cert'); } // Check key data if (!options.apn.key || !options.apn.key.length) { - console.error('ERROR: Push server could not find key'); + logger.error('ERROR: Push server could not find key'); } // Rig apn connection try { apnConnection = new apn.Provider(options.apn); } catch (e) { - console.error('Error trying to initialize APN'); - console.error(e); + logger.error('Error trying to initialize APN'); + logger.error(e); } }; diff --git a/app/push/server/gcm.js b/app/push/server/gcm.js index a677e630b196..dc3890825593 100644 --- a/app/push/server/gcm.js +++ b/app/push/server/gcm.js @@ -92,7 +92,7 @@ export const sendGCM = function({ userTokens, notification, _replaceToken, _remo sender.send(message, userTokens, 5, function(err, result) { if (err) { - logger.debug(`ANDROID ERROR: result of sender: ${ result }`); + logger.debug({ msg: 'ANDROID ERROR: result of sender', result }); return; } @@ -101,14 +101,14 @@ export const sendGCM = function({ userTokens, notification, _replaceToken, _remo return; } - logger.debug(`ANDROID: Result of sender: ${ JSON.stringify(result) }`); + logger.debug({ msg: 'ANDROID: Result of sender', result }); if (result.canonical_ids === 1 && userToken) { // This is an old device, token is replaced try { _replaceToken({ gcm: userToken }, { gcm: result.results[0].registration_id }); } catch (err) { - logger.error('Error replacing token', err); + logger.error({ msg: 'Error replacing token', err }); } } // We cant send to that token - might not be registered @@ -118,7 +118,7 @@ export const sendGCM = function({ userTokens, notification, _replaceToken, _remo try { _removeToken({ gcm: userToken }); } catch (err) { - logger.error('Error removing token', err); + logger.error({ msg: 'Error removing token', err }); } } }); diff --git a/app/push/server/logger.js b/app/push/server/logger.js index 553e253eee47..f770aef378f6 100644 --- a/app/push/server/logger.js +++ b/app/push/server/logger.js @@ -1,4 +1,3 @@ -import { Logger, LoggerManager } from '../../logger/server'; +import { Logger } from '../../../server/lib/logger/Logger'; export const logger = new Logger('Push'); -export { LoggerManager }; diff --git a/app/push/server/push.js b/app/push/server/push.js index e95ca8f88716..2d576fe3ea34 100644 --- a/app/push/server/push.js +++ b/app/push/server/push.js @@ -6,7 +6,7 @@ import _ from 'underscore'; import { initAPN, sendAPN } from './apn'; import { sendGCM } from './gcm'; -import { logger, LoggerManager } from './logger'; +import { logger } from './logger'; import { settings } from '../../settings/server'; export const _matchToken = Match.OneOf({ apn: String }, { gcm: String }); @@ -208,7 +208,7 @@ export class PushClass { return this.sendNotificationNative(app, notification, countApn, countGcm); }); - if (LoggerManager.logLevel === 2) { + if (settings.get('Log_Level') === '2') { logger.debug(`Sent message "${ notification.title }" to ${ countApn.length } ios apps ${ countGcm.length } android apps`); // Add some verbosity about the send result, making sure the developer diff --git a/app/search/server/logger/logger.js b/app/search/server/logger/logger.js index 86464e1c6acd..bd0ddbf10f4d 100644 --- a/app/search/server/logger/logger.js +++ b/app/search/server/logger/logger.js @@ -1,4 +1,4 @@ import { Logger } from '../../../logger'; -const SearchLogger = new Logger('Search Logger', {}); +const SearchLogger = new Logger('Search Logger'); export default SearchLogger; diff --git a/app/search/server/service/providerService.js b/app/search/server/service/providerService.js index ac913f8cfb46..2288a06e390b 100644 --- a/app/search/server/service/providerService.js +++ b/app/search/server/service/providerService.js @@ -142,7 +142,7 @@ Meteor.methods({ throw new Error('Provider currently not active'); } - SearchLogger.debug('search: ', `\n\tText:${ text }\n\tContext:${ JSON.stringify(context) }\n\tPayload:${ JSON.stringify(payload) }`); + SearchLogger.debug({ msg: 'search', text, context, payload }); searchProviderService.activeProvider.search(text, context, payload, (error, data) => { if (error) { @@ -163,7 +163,7 @@ Meteor.methods({ try { if (!searchProviderService.activeProvider) { throw new Error('Provider currently not active'); } - SearchLogger.debug('suggest: ', `\n\tText:${ text }\n\tContext:${ JSON.stringify(context) }\n\tPayload:${ JSON.stringify(payload) }`); + SearchLogger.debug({ msg: 'suggest', text, context, payload }); searchProviderService.activeProvider.suggest(text, context, payload, (error, data) => { if (error) { diff --git a/app/settings/server/functions/settings.ts b/app/settings/server/functions/settings.ts index 72ad2a970f73..7341393bc60a 100644 --- a/app/settings/server/functions/settings.ts +++ b/app/settings/server/functions/settings.ts @@ -7,6 +7,7 @@ import { SettingsBase } from '../../lib/settings'; import SettingsModel from '../../../models/server/models/Settings'; import { updateValue } from '../raw'; import { ISetting, SettingValue } from '../../../../definition/ISetting'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const blockedSettings = new Set(); const hiddenSettings = new Set(); @@ -131,7 +132,7 @@ class Settings extends SettingsBase { options.enterprise = options.enterprise || false; if (options.enterprise && !('invalidValue' in options)) { - console.error(`Enterprise setting ${ _id } is missing the invalidValue option`); + SystemLogger.error(`Enterprise setting ${ _id } is missing the invalidValue option`); throw new Error(`Enterprise setting ${ _id } is missing the invalidValue option`); } diff --git a/app/slackbridge/server/RocketAdapter.js b/app/slackbridge/server/RocketAdapter.js index e84efba8d201..db674910be44 100644 --- a/app/slackbridge/server/RocketAdapter.js +++ b/app/slackbridge/server/RocketAdapter.js @@ -5,7 +5,7 @@ import { Meteor } from 'meteor/meteor'; import { Accounts } from 'meteor/accounts-base'; import { Random } from 'meteor/random'; -import { logger } from './logger'; +import { rocketLogger } from './logger'; import { callbacks } from '../../callbacks'; import { settings } from '../../settings'; import { Messages, Rooms, Users } from '../../models'; @@ -13,7 +13,7 @@ import { createRoom, sendMessage, setUserAvatar } from '../../lib'; export default class RocketAdapter { constructor(slackBridge) { - logger.rocket.debug('constructor'); + rocketLogger.debug('constructor'); this.slackBridge = slackBridge; this.util = util; this.userTags = {}; @@ -39,7 +39,7 @@ export default class RocketAdapter { } registerForEvents() { - logger.rocket.debug('Register for events'); + rocketLogger.debug('Register for events'); callbacks.add('afterSaveMessage', this.onMessage.bind(this), callbacks.priority.LOW, 'SlackBridge_Out'); callbacks.add('afterDeleteMessage', this.onMessageDelete.bind(this), callbacks.priority.LOW, 'SlackBridge_Delete'); callbacks.add('setReaction', this.onSetReaction.bind(this), callbacks.priority.LOW, 'SlackBridge_SetReaction'); @@ -47,7 +47,7 @@ export default class RocketAdapter { } unregisterForEvents() { - logger.rocket.debug('Unregister for events'); + rocketLogger.debug('Unregister for events'); callbacks.remove('afterSaveMessage', 'SlackBridge_Out'); callbacks.remove('afterDeleteMessage', 'SlackBridge_Delete'); callbacks.remove('setReaction', 'SlackBridge_SetReaction'); @@ -61,10 +61,10 @@ export default class RocketAdapter { // This is on a channel that the rocket bot is not subscribed on this slack server return; } - logger.rocket.debug('onRocketMessageDelete', rocketMessageDeleted); + rocketLogger.debug('onRocketMessageDelete', rocketMessageDeleted); slack.postDeleteMessage(rocketMessageDeleted); } catch (err) { - logger.rocket.error('Unhandled error onMessageDelete', err); + rocketLogger.error('Unhandled error onMessageDelete', err); } }); } @@ -75,7 +75,7 @@ export default class RocketAdapter { return; } - logger.rocket.debug('onRocketSetReaction'); + rocketLogger.debug('onRocketSetReaction'); if (rocketMsgID && reaction) { if (this.slackBridge.reactionsMap.delete(`set${ rocketMsgID }${ reaction }`)) { @@ -94,7 +94,7 @@ export default class RocketAdapter { } } } catch (err) { - logger.rocket.error('Unhandled error onSetReaction', err); + rocketLogger.error('Unhandled error onSetReaction', err); } } @@ -104,7 +104,7 @@ export default class RocketAdapter { return; } - logger.rocket.debug('onRocketUnSetReaction'); + rocketLogger.debug('onRocketUnSetReaction'); if (rocketMsgID && reaction) { if (this.slackBridge.reactionsMap.delete(`unset${ rocketMsgID }${ reaction }`)) { @@ -124,7 +124,7 @@ export default class RocketAdapter { } } } catch (err) { - logger.rocket.error('Unhandled error onUnSetReaction', err); + rocketLogger.error('Unhandled error onUnSetReaction', err); } } @@ -135,7 +135,7 @@ export default class RocketAdapter { // This is on a channel that the rocket bot is not subscribed return; } - logger.rocket.debug('onRocketMessage', rocketMessage); + rocketLogger.debug('onRocketMessage', rocketMessage); if (rocketMessage.editedAt) { // This is an Edit Event @@ -154,7 +154,7 @@ export default class RocketAdapter { // A new message from Rocket.Chat this.processSendMessage(rocketMessage, slack); } catch (err) { - logger.rocket.error('Unhandled error onMessage', err); + rocketLogger.error('Unhandled error onMessage', err); } }); @@ -168,7 +168,7 @@ export default class RocketAdapter { } else { // They want to limit to certain groups const outSlackChannels = _.pluck(settings.get('SlackBridge_Out_Channels'), '_id') || []; - // logger.rocket.debug('Out SlackChannels: ', outSlackChannels); + // rocketLogger.debug('Out SlackChannels: ', outSlackChannels); if (outSlackChannels.indexOf(rocketMessage.rid) !== -1) { slack.postMessage(slack.getSlackChannel(rocketMessage.rid), rocketMessage); } @@ -260,7 +260,7 @@ export default class RocketAdapter { } addChannel(slackChannelID, hasRetried = false) { - logger.rocket.debug('Adding Rocket.Chat channel from Slack', slackChannelID); + rocketLogger.debug('Adding Rocket.Chat channel from Slack', slackChannelID); let addedRoom; this.slackAdapters.forEach((slack) => { @@ -272,7 +272,7 @@ export default class RocketAdapter { if (slackChannel) { const members = slack.slackAPI.getMembers(slackChannelID); if (!members) { - logger.rocket.error('Could not fetch room members'); + rocketLogger.error('Could not fetch room members'); return; } @@ -286,7 +286,7 @@ export default class RocketAdapter { const rocketUserCreator = this.getRocketUserCreator(slackChannel); if (!rocketUserCreator) { - logger.rocket.error('Could not fetch room creator information', slackChannel.creator); + rocketLogger.error('Could not fetch room creator information', slackChannel.creator); return; } @@ -296,12 +296,12 @@ export default class RocketAdapter { rocketChannel.rocketId = rocketChannel.rid; } catch (e) { if (!hasRetried) { - logger.rocket.debug('Error adding channel from Slack. Will retry in 1s.', e.message); + rocketLogger.debug('Error adding channel from Slack. Will retry in 1s.', e.message); // If first time trying to create channel fails, could be because of multiple messages received at the same time. Try again once after 1s. Meteor._sleepForMs(1000); return this.findChannel(slackChannelID) || this.addChannel(slackChannelID, true); } - console.log(e.message); + rocketLogger.error(e.message); } const roomUpdate = { @@ -327,7 +327,7 @@ export default class RocketAdapter { }); if (!addedRoom) { - logger.rocket.debug('Channel not added'); + rocketLogger.debug('Channel not added'); } return addedRoom; } @@ -341,7 +341,7 @@ export default class RocketAdapter { } addUser(slackUserID) { - logger.rocket.debug('Adding Rocket.Chat user from Slack', slackUserID); + rocketLogger.debug('Adding Rocket.Chat user from Slack', slackUserID); let addedUser; this.slackAdapters.forEach((slack) => { if (addedUser) { @@ -408,7 +408,7 @@ export default class RocketAdapter { try { setUserAvatar(user, url, null, 'url'); } catch (error) { - logger.rocket.debug('Error setting user avatar', error.message); + rocketLogger.debug('Error setting user avatar', error.message); } } } @@ -426,7 +426,7 @@ export default class RocketAdapter { }); if (!addedUser) { - logger.rocket.debug('User not added'); + rocketLogger.debug('User not added'); } return addedUser; @@ -495,7 +495,7 @@ export default class RocketAdapter { } }, 500); } else { - logger.rocket.debug('Send message to Rocket.Chat'); + rocketLogger.debug('Send message to Rocket.Chat'); sendMessage(rocketUser, rocketMsgObj, rocketChannel, true); } } diff --git a/app/slackbridge/server/SlackAdapter.js b/app/slackbridge/server/SlackAdapter.js index c61092f7cde5..1cb12c2bdacc 100644 --- a/app/slackbridge/server/SlackAdapter.js +++ b/app/slackbridge/server/SlackAdapter.js @@ -5,7 +5,7 @@ import https from 'https'; import { RTMClient } from '@slack/client'; import { Meteor } from 'meteor/meteor'; -import { logger } from './logger'; +import { slackLogger } from './logger'; import { SlackAPI } from './SlackAPI'; import { getUserAvatarURL } from '../../utils/lib/getUserAvatarURL'; import { Messages, Rooms, Users } from '../../models'; @@ -24,7 +24,7 @@ import { FileUpload } from '../../file-upload'; export default class SlackAdapter { constructor(slackBridge) { - logger.slack.debug('constructor'); + slackLogger.debug('constructor'); this.slackBridge = slackBridge; this.rtm = {}; // slack-client Real Time Messaging API this.apiToken = {}; // Slack API Token passed in via Connect @@ -56,7 +56,7 @@ export default class SlackAdapter { try { this.populateMembershipChannelMap(); // If run outside of Meteor.startup, HTTP is not defined } catch (err) { - logger.slack.error('Error attempting to connect to Slack', err); + slackLogger.error('Error attempting to connect to Slack', err); this.slackBridge.disconnect(); } }); @@ -74,9 +74,9 @@ export default class SlackAdapter { } registerForEvents() { - logger.slack.debug('Register for events'); + slackLogger.debug('Register for events'); this.rtm.on('authenticated', () => { - logger.slack.info('Connected to Slack'); + slackLogger.info('Connected to Slack'); }); this.rtm.on('unable_to_rtm_start', () => { @@ -84,7 +84,7 @@ export default class SlackAdapter { }); this.rtm.on('disconnected', () => { - logger.slack.info('Disconnected from Slack'); + slackLogger.info('Disconnected from Slack'); this.slackBridge.disconnect(); }); @@ -102,34 +102,34 @@ export default class SlackAdapter { * } **/ this.rtm.on('message', Meteor.bindEnvironment((slackMessage) => { - logger.slack.debug('OnSlackEvent-MESSAGE: ', slackMessage); + slackLogger.debug('OnSlackEvent-MESSAGE: ', slackMessage); if (slackMessage) { try { this.onMessage(slackMessage); } catch (err) { - logger.slack.error('Unhandled error onMessage', err); + slackLogger.error('Unhandled error onMessage', err); } } })); this.rtm.on('reaction_added', Meteor.bindEnvironment((reactionMsg) => { - logger.slack.debug('OnSlackEvent-REACTION_ADDED: ', reactionMsg); + slackLogger.debug('OnSlackEvent-REACTION_ADDED: ', reactionMsg); if (reactionMsg) { try { this.onReactionAdded(reactionMsg); } catch (err) { - logger.slack.error('Unhandled error onReactionAdded', err); + slackLogger.error('Unhandled error onReactionAdded', err); } } })); this.rtm.on('reaction_removed', Meteor.bindEnvironment((reactionMsg) => { - logger.slack.debug('OnSlackEvent-REACTION_REMOVED: ', reactionMsg); + slackLogger.debug('OnSlackEvent-REACTION_REMOVED: ', reactionMsg); if (reactionMsg) { try { this.onReactionRemoved(reactionMsg); } catch (err) { - logger.slack.error('Unhandled error onReactionRemoved', err); + slackLogger.error('Unhandled error onReactionRemoved', err); } } })); @@ -193,12 +193,12 @@ export default class SlackAdapter { * } **/ this.rtm.on('channel_left', Meteor.bindEnvironment((channelLeftMsg) => { - logger.slack.debug('OnSlackEvent-CHANNEL_LEFT: ', channelLeftMsg); + slackLogger.debug('OnSlackEvent-CHANNEL_LEFT: ', channelLeftMsg); if (channelLeftMsg) { try { this.onChannelLeft(channelLeftMsg); } catch (err) { - logger.slack.error('Unhandled error onChannelLeft', err); + slackLogger.error('Unhandled error onChannelLeft', err); } } })); @@ -365,7 +365,7 @@ export default class SlackAdapter { // Stash this away to key off it later so we don't send it back to Slack this.slackBridge.reactionsMap.set(`unset${ rocketMsg._id }${ rocketReaction }`, rocketUser); - logger.slack.debug('Removing reaction from Slack'); + slackLogger.debug('Removing reaction from Slack'); Meteor.runAsUser(rocketUser._id, () => { Meteor.call('setReaction', rocketReaction, rocketMsg._id); }); @@ -411,7 +411,7 @@ export default class SlackAdapter { // Stash this away to key off it later so we don't send it back to Slack this.slackBridge.reactionsMap.set(`set${ rocketMsg._id }${ rocketReaction }`, rocketUser); - logger.slack.debug('Adding reaction from Slack'); + slackLogger.debug('Adding reaction from Slack'); Meteor.runAsUser(rocketUser._id, () => { Meteor.call('setReaction', rocketReaction, rocketMsg._id); }); @@ -455,7 +455,7 @@ export default class SlackAdapter { } postFindChannel(rocketChannelName) { - logger.slack.debug('Searching for Slack channel or group', rocketChannelName); + slackLogger.debug('Searching for Slack channel or group', rocketChannelName); const channels = this.slackAPI.getChannels(); if (channels && channels.length > 0) { for (const channel of channels) { @@ -506,7 +506,7 @@ export default class SlackAdapter { addSlackChannel(rocketChID, slackChID) { const ch = this.getSlackChannel(rocketChID); if (ch == null) { - logger.slack.debug('Added channel', { rocketChID, slackChID }); + slackLogger.debug('Added channel', { rocketChID, slackChID }); this.slackChannelRocketBotMembershipMap.set(rocketChID, { id: slackChID, family: slackChID.charAt(0) === 'C' ? 'channels' : 'groups' }); } } @@ -558,7 +558,7 @@ export default class SlackAdapter { } populateMembershipChannelMap() { - logger.slack.debug('Populating channel map'); + slackLogger.debug('Populating channel map'); this.populateMembershipChannelMapByChannels(); this.populateMembershipChannelMapByGroups(); } @@ -575,10 +575,10 @@ export default class SlackAdapter { timestamp: slackTS, }; - logger.slack.debug('Posting Add Reaction to Slack'); + slackLogger.debug('Posting Add Reaction to Slack'); const postResult = this.slackAPI.react(data); if (postResult) { - logger.slack.debug('Reaction added to Slack'); + slackLogger.debug('Reaction added to Slack'); } } } @@ -595,10 +595,10 @@ export default class SlackAdapter { timestamp: slackTS, }; - logger.slack.debug('Posting Remove Reaction to Slack'); + slackLogger.debug('Posting Remove Reaction to Slack'); const postResult = this.slackAPI.removeReaction(data); if (postResult) { - logger.slack.debug('Reaction removed from Slack'); + slackLogger.debug('Reaction removed from Slack'); } } } @@ -615,10 +615,10 @@ export default class SlackAdapter { as_user: true, }; - logger.slack.debug('Post Delete Message to Slack', data); + slackLogger.debug('Post Delete Message to Slack', data); const postResult = this.slackAPI.removeMessage(data); if (postResult) { - logger.slack.debug('Message deleted on Slack'); + slackLogger.debug('Message deleted on Slack'); } } } @@ -674,7 +674,7 @@ export default class SlackAdapter { data.thread_ts = tmessage.slackTs; } } - logger.slack.debug('Post Message To Slack', data); + slackLogger.debug('Post Message To Slack', data); // If we don't have the bot id yet and we have multiple slack bridges, we need to keep track of the messages that are being sent if (!this.slackBotId && this.rocket.slackAdapters && this.rocket.slackAdapters.length >= 2) { @@ -690,7 +690,7 @@ export default class SlackAdapter { if (postResult.statusCode === 200 && postResult.data && postResult.data.message && postResult.data.message.bot_id && postResult.data.message.ts) { this.slackBotId = postResult.data.message.bot_id; Messages.setSlackBotIdAndSlackTs(rocketMessage._id, postResult.data.message.bot_id, postResult.data.message.ts); - logger.slack.debug(`RocketMsgID=${ rocketMessage._id } SlackMsgID=${ postResult.data.message.ts } SlackBotID=${ postResult.data.message.bot_id }`); + slackLogger.debug(`RocketMsgID=${ rocketMessage._id } SlackMsgID=${ postResult.data.message.ts } SlackBotID=${ postResult.data.message.bot_id }`); } } } @@ -707,16 +707,16 @@ export default class SlackAdapter { text: rocketMessage.msg, as_user: true, }; - logger.slack.debug('Post UpdateMessage To Slack', data); + slackLogger.debug('Post UpdateMessage To Slack', data); const postResult = this.slackAPI.updateMessage(data); if (postResult) { - logger.slack.debug('Message updated on Slack'); + slackLogger.debug('Message updated on Slack'); } } } processChannelJoin(slackMessage) { - logger.slack.debug('Channel join', slackMessage.channel.id); + slackLogger.debug('Channel join', slackMessage.channel.id); const rocketCh = this.rocket.addChannel(slackMessage.channel); if (rocketCh != null) { this.addSlackChannel(rocketCh._id, slackMessage.channel); @@ -775,7 +775,7 @@ export default class SlackAdapter { if (rocketMsgObj) { deleteMessage(rocketMsgObj, rocketUser); - logger.slack.debug('Rocket message deleted by Slack'); + slackLogger.debug('Rocket message deleted by Slack'); } } } @@ -802,7 +802,7 @@ export default class SlackAdapter { }; updateMessage(rocketMsgObj, rocketUser); - logger.slack.debug('Rocket message updated by Slack'); + slackLogger.debug('Rocket message updated by Slack'); } } } @@ -975,7 +975,7 @@ export default class SlackAdapter { return rocketMsgObj; } - logger.slack.error('Pinned item with no attachment'); + slackLogger.error('Pinned item with no attachment'); } processSubtypedMessage(rocketChannel, rocketUser, slackMessage, isImporting) { @@ -1015,15 +1015,15 @@ export default class SlackAdapter { case 'file_share': return this.processShareMessage(rocketChannel, rocketUser, slackMessage, isImporting); case 'file_comment': - logger.slack.error('File comment not implemented'); + slackLogger.error('File comment not implemented'); return; case 'file_mention': - logger.slack.error('File mentioned not implemented'); + slackLogger.error('File mentioned not implemented'); return; case 'pinned_item': return this.processPinnedItemMessage(rocketChannel, rocketUser, slackMessage, isImporting); case 'unpinned_item': - logger.slack.error('Unpinned item not implemented'); + slackLogger.error('Unpinned item not implemented'); } } @@ -1096,12 +1096,12 @@ export default class SlackAdapter { } importFromHistory(family, options) { - logger.slack.debug('Importing messages history'); + slackLogger.debug('Importing messages history'); const data = this.slackAPI.getHistory(family, options); if (Array.isArray(data.messages) && data.messages.length) { let latest = 0; for (const message of data.messages.reverse()) { - logger.slack.debug('MESSAGE: ', message); + slackLogger.debug('MESSAGE: ', message); if (!latest || message.ts > latest) { latest = message.ts; } @@ -1113,7 +1113,7 @@ export default class SlackAdapter { } copyChannelInfo(rid, channelMap) { - logger.slack.debug('Copying users from Slack channel to Rocket.Chat', channelMap.id, rid); + slackLogger.debug('Copying users from Slack channel to Rocket.Chat', channelMap.id, rid); const channel = this.slackAPI.getRoomInfo(channelMap.id); if (channel) { const members = this.slackAPI.getMembers(channelMap.id); @@ -1121,7 +1121,7 @@ export default class SlackAdapter { for (const member of members) { const user = this.rocket.findUser(member) || this.rocket.addUser(member); if (user) { - logger.slack.debug('Adding user to room', user.username, rid); + slackLogger.debug('Adding user to room', user.username, rid); addUserToRoom(rid, user, null, true); } } @@ -1150,7 +1150,7 @@ export default class SlackAdapter { if (topic) { const creator = this.rocket.findUser(topic_creator) || this.rocket.addUser(topic_creator); - logger.slack.debug('Setting room topic', rid, topic, creator.username); + slackLogger.debug('Setting room topic', rid, topic, creator.username); saveRoomTopic(rid, topic, creator, false); } } @@ -1185,19 +1185,19 @@ export default class SlackAdapter { } importMessages(rid, callback) { - logger.slack.info('importMessages: ', rid); + slackLogger.info('importMessages: ', rid); const rocketchat_room = Rooms.findOneById(rid); if (rocketchat_room) { if (this.getSlackChannel(rid)) { this.copyChannelInfo(rid, this.getSlackChannel(rid)); - logger.slack.debug('Importing messages from Slack to Rocket.Chat', this.getSlackChannel(rid), rid); + slackLogger.debug('Importing messages from Slack to Rocket.Chat', this.getSlackChannel(rid), rid); let results = this.importFromHistory(this.getSlackChannel(rid).family, { channel: this.getSlackChannel(rid).id, oldest: 1 }); while (results && results.has_more) { results = this.importFromHistory(this.getSlackChannel(rid).family, { channel: this.getSlackChannel(rid).id, oldest: results.ts }); } - logger.slack.debug('Pinning Slack channel messages to Rocket.Chat', this.getSlackChannel(rid), rid); + slackLogger.debug('Pinning Slack channel messages to Rocket.Chat', this.getSlackChannel(rid), rid); this.copyPins(rid, this.getSlackChannel(rid)); return callback(); @@ -1207,10 +1207,10 @@ export default class SlackAdapter { this.addSlackChannel(rid, slack_room.id); return this.importMessages(rid, callback); } - logger.slack.error('Could not find Slack room with specified name', rocketchat_room.name); + slackLogger.error('Could not find Slack room with specified name', rocketchat_room.name); return callback(new Meteor.Error('error-slack-room-not-found', 'Could not find Slack room with specified name')); } - logger.slack.error('Could not find Rocket.Chat room with specified id', rid); + slackLogger.error('Could not find Rocket.Chat room with specified id', rid); return callback(new Meteor.Error('error-invalid-room', 'Invalid room')); } } diff --git a/app/slackbridge/server/logger.js b/app/slackbridge/server/logger.js index f8cf66078391..6f25e8015ff3 100644 --- a/app/slackbridge/server/logger.js +++ b/app/slackbridge/server/logger.js @@ -1,11 +1,8 @@ import { Logger } from '../../logger'; -export const logger = new Logger('SlackBridge', { - sections: { - connection: 'Connection', - events: 'Events', - class: 'Class', - slack: 'Slack', - rocket: 'Rocket', - }, -}); +export const logger = new Logger('SlackBridge'); + +export const connLogger = logger.section('Connection'); +export const classLogger = logger.section('Class'); +export const slackLogger = logger.section('Slack'); +export const rocketLogger = logger.section('Rocket'); diff --git a/app/slackbridge/server/slackbridge.js b/app/slackbridge/server/slackbridge.js index 0c3e7b9e6d42..addb0c1a2e9a 100644 --- a/app/slackbridge/server/slackbridge.js +++ b/app/slackbridge/server/slackbridge.js @@ -1,6 +1,6 @@ import SlackAdapter from './SlackAdapter.js'; import RocketAdapter from './RocketAdapter.js'; -import { logger } from './logger'; +import { classLogger, connLogger } from './logger'; import { settings } from '../../settings'; /** @@ -44,7 +44,7 @@ class SlackBridgeClass { } this.connected = true; - logger.connection.info('Enabled'); + connLogger.info('Enabled'); } } @@ -56,7 +56,7 @@ class SlackBridgeClass { }); this.slackAdapters = []; this.connected = false; - logger.connection.info('Disabled'); + connLogger.info('Disabled'); } } @@ -71,25 +71,25 @@ class SlackBridgeClass { } } - logger.class.debug(`Setting: ${ key }`, value); + classLogger.debug(`Setting: ${ key }`, value); }); // Import messages from Slack with an alias; %s is replaced by the username of the user. If empty, no alias will be used. settings.get('SlackBridge_AliasFormat', (key, value) => { this.aliasFormat = value; - logger.class.debug(`Setting: ${ key }`, value); + classLogger.debug(`Setting: ${ key }`, value); }); // Do not propagate messages from bots whose name matches the regular expression above. If left empty, all messages from bots will be propagated. settings.get('SlackBridge_ExcludeBotnames', (key, value) => { this.excludeBotnames = value; - logger.class.debug(`Setting: ${ key }`, value); + classLogger.debug(`Setting: ${ key }`, value); }); // Reactions settings.get('SlackBridge_Reactions_Enabled', (key, value) => { this.isReactionsEnabled = value; - logger.class.debug(`Setting: ${ key }`, value); + classLogger.debug(`Setting: ${ key }`, value); }); // Is this entire SlackBridge enabled @@ -99,7 +99,7 @@ class SlackBridgeClass { } else { this.disconnect(); } - logger.class.debug(`Setting: ${ key }`, value); + classLogger.debug(`Setting: ${ key }`, value); }); } } diff --git a/app/sms/server/services/mobex.js b/app/sms/server/services/mobex.js index 1f41dece2210..a85f1650e65d 100644 --- a/app/sms/server/services/mobex.js +++ b/app/sms/server/services/mobex.js @@ -3,6 +3,7 @@ import { Base64 } from 'meteor/base64'; import { settings } from '../../../settings'; import { SMS } from '../SMS'; +import { SystemLogger } from '../../../../server/lib/logger/system'; class Mobex { constructor() { @@ -27,7 +28,7 @@ class Mobex { } if (isNaN(numMedia)) { - console.error(`Error parsing NumMedia ${ data.NumMedia }`); + SystemLogger.error(`Error parsing NumMedia ${ data.NumMedia }`); return returnData; } @@ -84,7 +85,7 @@ class Mobex { } } catch (e) { result.resultMsg = `Error while sending SMS with Mobex. Detail: ${ e }`; - console.error('Error while sending SMS with Mobex', e); + SystemLogger.error('Error while sending SMS with Mobex', e); } return result; @@ -129,7 +130,7 @@ class Mobex { result.response = response; } catch (e) { result.resultMsg = `Error while sending SMS with Mobex. Detail: ${ e }`; - console.error('Error while sending SMS with Mobex', e); + SystemLogger.error('Error while sending SMS with Mobex', e); } return result; diff --git a/app/sms/server/services/twilio.js b/app/sms/server/services/twilio.js index bf52dcd5491f..eeae457ff694 100644 --- a/app/sms/server/services/twilio.js +++ b/app/sms/server/services/twilio.js @@ -7,6 +7,7 @@ import { settings } from '../../../settings'; import { SMS } from '../SMS'; import { fileUploadIsValidContentType } from '../../../utils/lib/fileUploadRestrictions'; import { api } from '../../../../server/sdk/api'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const MAX_FILE_SIZE = 5242880; @@ -49,7 +50,7 @@ class Twilio { } if (isNaN(numMedia)) { - console.error(`Error parsing NumMedia ${ data.NumMedia }`); + SystemLogger.error(`Error parsing NumMedia ${ data.NumMedia }`); return returnData; } @@ -98,7 +99,7 @@ class Twilio { if (reason) { rid && userId && notifyAgent(userId, rid, reason); - return console.error(`(Twilio) -> ${ reason }`); + return SystemLogger.error(`(Twilio) -> ${ reason }`); } mediaUrl = [publicFilePath]; diff --git a/app/sms/server/services/voxtelesys.js b/app/sms/server/services/voxtelesys.js index 3b0c7dd0ae92..c2b00e59d2e3 100644 --- a/app/sms/server/services/voxtelesys.js +++ b/app/sms/server/services/voxtelesys.js @@ -8,6 +8,7 @@ import { SMS } from '../SMS'; import { fileUploadIsValidContentType } from '../../../utils/lib/fileUploadRestrictions'; import { mime } from '../../../utils/lib/mimeTypes'; import { api } from '../../../../server/sdk/api'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const MAX_FILE_SIZE = 5242880; @@ -79,7 +80,7 @@ class Voxtelesys { if (reason) { rid && userId && notifyAgent(userId, rid, reason); - return console.error(`(Voxtelesys) -> ${ reason }`); + return SystemLogger.error(`(Voxtelesys) -> ${ reason }`); } media = [publicFilePath]; @@ -100,7 +101,7 @@ class Voxtelesys { try { HTTP.call('POST', this.URL || 'https://smsapi.voxtelesys.net/api/v1/sms', options); } catch (error) { - console.error(`Error connecting to Voxtelesys SMS API: ${ error }`); + SystemLogger.error(`Error connecting to Voxtelesys SMS API: ${ error }`); } } diff --git a/app/theme/server/server.js b/app/theme/server/server.js index b1a55d40ac20..fbdc4fcee936 100644 --- a/app/theme/server/server.js +++ b/app/theme/server/server.js @@ -10,13 +10,7 @@ import { settings } from '../../settings'; import { Logger } from '../../logger'; import { addStyle } from '../../ui-master/server/inject'; -const logger = new Logger('rocketchat:theme', { - methods: { - stop_rendering: { - type: 'info', - }, - }, -}); +const logger = new Logger('rocketchat:theme'); let currentHash = ''; let currentSize = 0; @@ -69,9 +63,9 @@ export const theme = new class { }; const start = Date.now(); return less.render(content, options, function(err, data) { - logger.stop_rendering(Date.now() - start); + logger.info({ stop_rendering: Date.now() - start }); if (err != null) { - return console.log(err); + return logger.error(err); } settings.updateById('css', data.css); diff --git a/app/utils/lib/templateVarHandler.js b/app/utils/lib/templateVarHandler.js index 463a48ed34e3..dba5cdef43bf 100644 --- a/app/utils/lib/templateVarHandler.js +++ b/app/utils/lib/templateVarHandler.js @@ -3,8 +3,8 @@ import { Meteor } from 'meteor/meteor'; let logger; if (Meteor.isServer) { - const { Logger } = require('../../logger/server/server'); - logger = new Logger('TemplateVarHandler', {}); + const { Logger } = require('../../../server/lib/logger/Logger'); + logger = new Logger('TemplateVarHandler'); } export const templateVarHandler = function(variable, object) { diff --git a/app/videobridge/server/methods/bbb.js b/app/videobridge/server/methods/bbb.js index 3695cc389cd3..4721dc9842ce 100644 --- a/app/videobridge/server/methods/bbb.js +++ b/app/videobridge/server/methods/bbb.js @@ -3,9 +3,10 @@ import { HTTP } from 'meteor/http'; import xml2js from 'xml2js'; import BigBlueButtonApi from '../../../bigbluebutton/server'; -import { settings } from '../../../settings'; -import { Rooms, Users } from '../../../models'; -import { saveStreamingOptions } from '../../../channel-settings'; +import { SystemLogger } from '../../../../server/lib/logger/system'; +import { settings } from '../../../settings/server'; +import { Rooms, Users } from '../../../models/server'; +import { saveStreamingOptions } from '../../../channel-settings/server'; import { API } from '../../../api/server'; const parser = new xml2js.Parser({ @@ -66,7 +67,7 @@ Meteor.methods({ if (hookResult.statusCode !== 200) { // TODO improve error logging - console.log({ hookResult }); + SystemLogger.error(hookResult); return; } @@ -130,7 +131,7 @@ API.v1.addRoute('videoconference.bbb.update/:id', { authRequired: false }, { const meetingID = event.data.attributes.meeting['external-meeting-id']; const rid = meetingID.replace(settings.get('uniqueID'), ''); - console.log(eventType, rid); + SystemLogger.debug(eventType, rid); if (eventType === 'meeting-ended') { saveStreamingOptions(rid, {}); @@ -147,14 +148,14 @@ API.v1.addRoute('videoconference.bbb.update/:id', { authRequired: false }, { // if (getMeetingInfoResult.statusCode !== 200) { // // TODO improve error logging - // console.log({ getMeetingInfoResult }); + // SystemLogger.error({ getMeetingInfoResult }); // } // const doc = parseString(getMeetingInfoResult.content); // if (doc.response.returncode[0]) { // const participantCount = parseInt(doc.response.participantCount[0]); - // console.log(participantCount); + // SystemLogger.debug(participantCount); // } // } }, diff --git a/app/videobridge/server/methods/jitsiSetTimeout.js b/app/videobridge/server/methods/jitsiSetTimeout.js index 3f630067d222..bfb109efd322 100644 --- a/app/videobridge/server/methods/jitsiSetTimeout.js +++ b/app/videobridge/server/methods/jitsiSetTimeout.js @@ -6,7 +6,7 @@ import { callbacks } from '../../../callbacks/server'; import { metrics } from '../../../metrics/server'; import * as CONSTANTS from '../../constants'; import { canSendMessage } from '../../../authorization/server'; -import { SystemLogger } from '../../../logger/server'; +import { SystemLogger } from '../../../../server/lib/logger/system'; Meteor.methods({ 'jitsi:updateTimeout': (rid, joiningNow = true) => { diff --git a/app/webdav/server/methods/uploadFileToWebdav.ts b/app/webdav/server/methods/uploadFileToWebdav.ts index b818579dcf1d..345550285e7f 100644 --- a/app/webdav/server/methods/uploadFileToWebdav.ts +++ b/app/webdav/server/methods/uploadFileToWebdav.ts @@ -6,7 +6,7 @@ import { getWebdavCredentials } from './getWebdavCredentials'; import { WebdavAccounts } from '../../../models/server'; import { WebdavClientAdapter } from '../lib/webdavClientAdapter'; -const logger = new Logger('WebDAV_Upload', {}); +const logger = new Logger('WebDAV_Upload'); Meteor.methods({ async uploadFileToWebdav(accountId, fileData, name) { diff --git a/ee/app/livechat-enterprise/server/hooks/afterForwardChatToDepartment.js b/ee/app/livechat-enterprise/server/hooks/afterForwardChatToDepartment.js index 510ef1cbf463..b1385fb9f202 100644 --- a/ee/app/livechat-enterprise/server/hooks/afterForwardChatToDepartment.js +++ b/ee/app/livechat-enterprise/server/hooks/afterForwardChatToDepartment.js @@ -1,32 +1,32 @@ import { callbacks } from '../../../../../app/callbacks/server'; import LivechatRooms from '../../../../../app/models/server/models/LivechatRooms'; import LivechatDepartment from '../../../../../app/models/server/models/LivechatDepartment'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.afterForwardChatToDepartment', (options) => { const { rid, newDepartmentId } = options; const room = LivechatRooms.findOneById(rid); if (!room) { - logger.cb.debug('Skipping callback. No room found'); + cbLogger.debug('Skipping callback. No room found'); return options; } LivechatRooms.unsetPredictedVisitorAbandonmentByRoomId(room._id); const department = LivechatDepartment.findOneById(newDepartmentId, { fields: { ancestors: 1 } }); if (!department) { - logger.cb.debug('Skipping callback. No department found'); + cbLogger.debug('Skipping callback. No department found'); return options; } const { departmentAncestors } = room; const { ancestors } = department; if (!ancestors && !departmentAncestors) { - logger.cb.debug('Skipping callback. No ancestors found for department'); + cbLogger.debug('Skipping callback. No ancestors found for department'); return options; } - logger.cb.debug(`Updating department ${ newDepartmentId } ancestors for room ${ rid }`); + cbLogger.debug(`Updating department ${ newDepartmentId } ancestors for room ${ rid }`); LivechatRooms.updateDepartmentAncestorsById(room._id, ancestors); return options; diff --git a/ee/app/livechat-enterprise/server/hooks/afterInquiryQueued.ts b/ee/app/livechat-enterprise/server/hooks/afterInquiryQueued.ts index f60aa0589d45..0f9c7661b910 100644 --- a/ee/app/livechat-enterprise/server/hooks/afterInquiryQueued.ts +++ b/ee/app/livechat-enterprise/server/hooks/afterInquiryQueued.ts @@ -3,18 +3,18 @@ import moment from 'moment'; import { callbacks } from '../../../../../app/callbacks/server'; import { LivechatInquiry } from '../../../../../app/models/server'; import { settings } from '../../../../../app/settings/server'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; let timer = 0; const setQueueTimer = (inquiry: any): void => { if (!inquiry?._id) { - (logger as any).cb.debug('Skipping callback. No inquiry provided'); + cbLogger.debug('Skipping callback. No inquiry provided'); return; } const newQueueTime = moment(inquiry?._updatedAt).add(timer, 'minutes'); - (logger as any).cb.debug(`Setting estimated inactivity close time to ${ newQueueTime } for inquiry ${ inquiry._id }`); + cbLogger.debug(`Setting estimated inactivity close time to ${ newQueueTime } for inquiry ${ inquiry._id }`); (LivechatInquiry as any).setEstimatedInactivityCloseTime(inquiry?._id, newQueueTime); }; diff --git a/ee/app/livechat-enterprise/server/hooks/afterOnHold.ts b/ee/app/livechat-enterprise/server/hooks/afterOnHold.ts index 2fd4506deb04..f42e19bbebc4 100644 --- a/ee/app/livechat-enterprise/server/hooks/afterOnHold.ts +++ b/ee/app/livechat-enterprise/server/hooks/afterOnHold.ts @@ -3,7 +3,7 @@ import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import { callbacks } from '../../../../../app/callbacks/server'; import { settings } from '../../../../../app/settings/server'; import { AutoCloseOnHoldScheduler } from '../lib/AutoCloseOnHoldScheduler'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; const DEFAULT_CLOSED_MESSAGE = TAPi18n.__('Closed_automatically'); @@ -14,16 +14,16 @@ let customCloseMessage = DEFAULT_CLOSED_MESSAGE; const handleAfterOnHold = async (room: any = {}): Promise => { const { _id: rid } = room; if (!rid) { - (logger as any).cb.debug('Skipping callback. No room provided'); + cbLogger.debug('Skipping callback. No room provided'); return; } if (!autoCloseOnHoldChatTimeout || autoCloseOnHoldChatTimeout <= 0) { - (logger as any).cb.debug('Skipping callback. Autoclose on hold disabled by setting'); + cbLogger.debug('Skipping callback. Autoclose on hold disabled by setting'); return; } - (logger as any).cb.debug(`Scheduling room ${ rid } to be closed in ${ autoCloseOnHoldChatTimeout } seconds`); + cbLogger.debug(`Scheduling room ${ rid } to be closed in ${ autoCloseOnHoldChatTimeout } seconds`); await AutoCloseOnHoldScheduler.scheduleRoom(room._id, autoCloseOnHoldChatTimeout, customCloseMessage); }; diff --git a/ee/app/livechat-enterprise/server/hooks/afterOnHoldChatResumed.ts b/ee/app/livechat-enterprise/server/hooks/afterOnHoldChatResumed.ts index 46127d6ee441..b116dc690d2b 100644 --- a/ee/app/livechat-enterprise/server/hooks/afterOnHoldChatResumed.ts +++ b/ee/app/livechat-enterprise/server/hooks/afterOnHoldChatResumed.ts @@ -1,14 +1,14 @@ import { callbacks } from '../../../../../app/callbacks/server'; import { LivechatEnterprise } from '../lib/LivechatEnterprise'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; const handleAfterOnHoldChatResumed = async (room: any): Promise => { if (!room || !room._id || !room.onHold) { - (logger as any).cb.debug('Skipping callback. No room provided or room is not on hold'); + cbLogger.debug('Skipping callback. No room provided or room is not on hold'); return; } - (logger as any).cb.debug(`Removing current on hold timers for room ${ room._id }`); + cbLogger.debug(`Removing current on hold timers for room ${ room._id }`); LivechatEnterprise.releaseOnHoldChat(room); }; diff --git a/ee/app/livechat-enterprise/server/hooks/afterReturnRoomAsInquiry.ts b/ee/app/livechat-enterprise/server/hooks/afterReturnRoomAsInquiry.ts index 0091711c484e..79e25af766ef 100644 --- a/ee/app/livechat-enterprise/server/hooks/afterReturnRoomAsInquiry.ts +++ b/ee/app/livechat-enterprise/server/hooks/afterReturnRoomAsInquiry.ts @@ -1,11 +1,11 @@ import { callbacks } from '../../../../../app/callbacks/server'; import { LivechatRooms } from '../../../../../app/models/server'; import { settings } from '../../../../../app/settings/server'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; const unsetPredictedVisitorAbandonment = ({ room }: { room: any }): void => { if (!room?._id || !room?.omnichannel?.predictedVisitorAbandonmentAt) { - (logger as any).cb.debug('Skipping callback. No room or no visitor abandonment info'); + cbLogger.debug('Skipping callback. No room or no visitor abandonment info'); return; } diff --git a/ee/app/livechat-enterprise/server/hooks/afterTakeInquiry.js b/ee/app/livechat-enterprise/server/hooks/afterTakeInquiry.js index 928391cbff35..328d855e1fec 100644 --- a/ee/app/livechat-enterprise/server/hooks/afterTakeInquiry.js +++ b/ee/app/livechat-enterprise/server/hooks/afterTakeInquiry.js @@ -1,22 +1,22 @@ import { callbacks } from '../../../../../app/callbacks'; import { settings } from '../../../../../app/settings'; import { dispatchWaitingQueueStatus } from '../lib/Helper'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.afterTakeInquiry', async (inquiry) => { if (!settings.get('Livechat_waiting_queue')) { - logger.cb.debug('Skipping callback. Waiting queue disabled by setting'); + cbLogger.debug('Skipping callback. Waiting queue disabled by setting'); return inquiry; } if (!inquiry) { - logger.cb.debug('Skipping callback. No inquiry provided'); + cbLogger.debug('Skipping callback. No inquiry provided'); return null; } const { department } = inquiry; await dispatchWaitingQueueStatus(department); - logger.cb.debug(`Statuses for queue ${ department || 'Public' } updated succesfully`); + cbLogger.debug(`Statuses for queue ${ department || 'Public' } updated succesfully`); return inquiry; }, callbacks.priority.MEDIUM, 'livechat-after-take-inquiry'); diff --git a/ee/app/livechat-enterprise/server/hooks/applyDepartmentRestrictions.ts b/ee/app/livechat-enterprise/server/hooks/applyDepartmentRestrictions.ts index f2a67b7bdec5..70e0577230f0 100644 --- a/ee/app/livechat-enterprise/server/hooks/applyDepartmentRestrictions.ts +++ b/ee/app/livechat-enterprise/server/hooks/applyDepartmentRestrictions.ts @@ -1,14 +1,14 @@ import { callbacks } from '../../../../../app/callbacks/server'; import { addQueryRestrictionsToDepartmentsModel } from '../lib/query.helper'; import { hasRole } from '../../../../../app/authorization/server/functions/hasRole'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.applyDepartmentRestrictions', (originalQuery = {}, { userId } = { userId: null }) => { if (!userId || !hasRole(userId, 'livechat-monitor')) { - (logger as any).cb.debug('Skipping callback. No user id provided or user is not a monitor'); + cbLogger.debug('Skipping callback. No user id provided or user is not a monitor'); return originalQuery; } - (logger as any).cb.debug('Applying department query restrictions'); + cbLogger.debug('Applying department query restrictions'); return addQueryRestrictionsToDepartmentsModel(originalQuery); }, callbacks.priority.HIGH, 'livechat-apply-department-restrictions'); diff --git a/ee/app/livechat-enterprise/server/hooks/applySimultaneousChatsRestrictions.ts b/ee/app/livechat-enterprise/server/hooks/applySimultaneousChatsRestrictions.ts index ae020b2bbcb8..2a27bfdf951b 100644 --- a/ee/app/livechat-enterprise/server/hooks/applySimultaneousChatsRestrictions.ts +++ b/ee/app/livechat-enterprise/server/hooks/applySimultaneousChatsRestrictions.ts @@ -1,13 +1,13 @@ import { callbacks } from '../../../../../app/callbacks/server'; import { LivechatDepartment } from '../../../../../app/models/server'; import { settings } from '../../../../../app/settings/server'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.applySimultaneousChatRestrictions', (_: any, { departmentId }: { departmentId?: string }) => { if (departmentId) { const departmentLimit = LivechatDepartment.findOneById(departmentId)?.maxNumberSimultaneousChat || 0; if (departmentLimit > 0) { - (logger as any).cb.debug(`Applying department filters. Max chats per department ${ departmentLimit }`); + cbLogger.debug(`Applying department filters. Max chats per department ${ departmentLimit }`); return { $match: { 'queueInfo.chats': { $gte: Number(departmentLimit) } } }; } } @@ -34,7 +34,7 @@ callbacks.add('livechat.applySimultaneousChatRestrictions', (_: any, { departmen // dummy filter meaning: don't match anything : { _id: '' }; - (logger as any).cb.debug(`Applying agent & global filters. Max number of chats allowed to all agents by setting: ${ maxChatsPerSetting }`); + cbLogger.debug(`Applying agent & global filters. Max number of chats allowed to all agents by setting: ${ maxChatsPerSetting }`); return { $match: { $or: [agentFilter, globalFilter] } }; }, callbacks.priority.HIGH, 'livechat-apply-simultaneous-restrictions'); diff --git a/ee/app/livechat-enterprise/server/hooks/beforeForwardRoomToDepartment.js b/ee/app/livechat-enterprise/server/hooks/beforeForwardRoomToDepartment.js index 503e4d3afc94..7df2f6b56f54 100644 --- a/ee/app/livechat-enterprise/server/hooks/beforeForwardRoomToDepartment.js +++ b/ee/app/livechat-enterprise/server/hooks/beforeForwardRoomToDepartment.js @@ -2,29 +2,29 @@ import { Meteor } from 'meteor/meteor'; import { callbacks } from '../../../../../app/callbacks'; import { LivechatDepartment } from '../../../../../app/models/server'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.beforeForwardRoomToDepartment', (options) => { const { room, transferData } = options; if (!room || !transferData) { - logger.cb.debug('Skipping callback. No room provided'); + cbLogger.debug('Skipping callback. No room provided'); return options; } const { departmentId } = room; if (!departmentId) { - logger.cb.debug('Skipping callback. No department provided'); + cbLogger.debug('Skipping callback. No department provided'); return options; } const { department: departmentToTransfer } = transferData; const currentDepartment = LivechatDepartment.findOneById(departmentId); if (!currentDepartment) { - logger.cb.debug('Skipping callback. Current department does not exists'); + cbLogger.debug('Skipping callback. Current department does not exists'); return options; } const { departmentsAllowedToForward } = currentDepartment; const isAllowedToTransfer = !departmentsAllowedToForward || (Array.isArray(departmentsAllowedToForward) && departmentsAllowedToForward.includes(departmentToTransfer._id)); if (isAllowedToTransfer) { - logger.cb.debug(`Callback success. Room ${ room._id } can be forwarded to department ${ departmentToTransfer._id }`); + cbLogger.debug(`Callback success. Room ${ room._id } can be forwarded to department ${ departmentToTransfer._id }`); return options; } throw new Meteor.Error('error-forwarding-department-target-not-allowed', 'The forwarding to the target department is not allowed.'); diff --git a/ee/app/livechat-enterprise/server/hooks/beforeNewInquiry.js b/ee/app/livechat-enterprise/server/hooks/beforeNewInquiry.js index 5607d196534e..73b1d3ff71b4 100644 --- a/ee/app/livechat-enterprise/server/hooks/beforeNewInquiry.js +++ b/ee/app/livechat-enterprise/server/hooks/beforeNewInquiry.js @@ -3,12 +3,12 @@ import { Meteor } from 'meteor/meteor'; import { callbacks } from '../../../../../app/callbacks'; import { settings } from '../../../../../app/settings'; import LivechatPriority from '../../../models/server/models/LivechatPriority'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.beforeInquiry', (extraData = {}) => { const { priority: searchTerm, ...props } = extraData; if (!searchTerm) { - logger.cb.debug('Skipping callback. No search param provided'); + cbLogger.debug('Skipping callback. No search param provided'); return extraData; } @@ -23,20 +23,20 @@ callbacks.add('livechat.beforeInquiry', (extraData = {}) => { const queueOrder = 0; const estimatedServiceTimeAt = new Date(now.setMinutes(now.getMinutes() + estimatedWaitingTimeQueue)); - logger.cb.debug('Callback success. Queue timing properties added'); + cbLogger.debug('Callback success. Queue timing properties added'); return Object.assign({ ...props }, { ts, queueOrder, estimatedWaitingTimeQueue, estimatedServiceTimeAt }); }, callbacks.priority.MEDIUM, 'livechat-before-new-inquiry'); callbacks.add('livechat.beforeInquiry', (extraData = {}) => { const queueInactivityAction = settings.get('Livechat_max_queue_wait_time_action'); if (!queueInactivityAction || queueInactivityAction === 'Nothing') { - logger.cb.debug('Skipping callback. Disabled by setting'); + cbLogger.debug('Skipping callback. Disabled by setting'); return extraData; } const maxQueueWaitTimeMinutes = settings.get('Livechat_max_queue_wait_time'); const estimatedInactivityCloseTimeAt = new Date(new Date().getTime() + maxQueueWaitTimeMinutes * 60000); - logger.cb.debug(`Setting maximum queue wait time to ${ maxQueueWaitTimeMinutes } minutes`); + cbLogger.debug(`Setting maximum queue wait time to ${ maxQueueWaitTimeMinutes } minutes`); return Object.assign(extraData, { estimatedInactivityCloseTimeAt }); }, callbacks.priority.MEDIUM, 'livechat-before-new-inquiry-append-queue-timer'); diff --git a/ee/app/livechat-enterprise/server/hooks/beforeRoutingChat.js b/ee/app/livechat-enterprise/server/hooks/beforeRoutingChat.js index faaafbd2bfb4..2ebf692e7726 100644 --- a/ee/app/livechat-enterprise/server/hooks/beforeRoutingChat.js +++ b/ee/app/livechat-enterprise/server/hooks/beforeRoutingChat.js @@ -4,28 +4,28 @@ import { LivechatInquiry } from '../../../../../app/models/server'; import { dispatchInquiryPosition } from '../lib/Helper'; import { allowAgentSkipQueue } from '../../../../../app/livechat/server/lib/Helper'; import { saveQueueInquiry } from '../../../../../app/livechat/server/lib/QueueManager'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.beforeRouteChat', async (inquiry, agent) => { if (!settings.get('Livechat_waiting_queue')) { - logger.cb.debug('Skipping callback. Waiting queue disabled by setting'); + cbLogger.debug('Skipping callback. Waiting queue disabled by setting'); return inquiry; } if (!inquiry) { - logger.cb.debug('Skipping callback. No inquiry provided'); + cbLogger.debug('Skipping callback. No inquiry provided'); return inquiry; } const { _id, status, department } = inquiry; if (status !== 'ready') { - logger.cb.debug(`Skipping callback. Inquiry ${ _id } is ready`); + cbLogger.debug(`Skipping callback. Inquiry ${ _id } is ready`); return inquiry; } if (agent && allowAgentSkipQueue(agent)) { - logger.cb.debug(`Skipping callback. Agent ${ agent.agentId } can skip queue`); + cbLogger.debug(`Skipping callback. Agent ${ agent.agentId } can skip queue`); return inquiry; } @@ -36,6 +36,6 @@ callbacks.add('livechat.beforeRouteChat', async (inquiry, agent) => { dispatchInquiryPosition(inq); } - logger.cb.debug(`Callback success. Inquiry ${ _id } position has been notified`); + cbLogger.debug(`Callback success. Inquiry ${ _id } position has been notified`); return LivechatInquiry.findOneById(_id); }, callbacks.priority.HIGH, 'livechat-before-routing-chat'); diff --git a/ee/app/livechat-enterprise/server/hooks/checkAgentBeforeTakeInquiry.js b/ee/app/livechat-enterprise/server/hooks/checkAgentBeforeTakeInquiry.js index d9ac8c559e0a..175c1bb12102 100644 --- a/ee/app/livechat-enterprise/server/hooks/checkAgentBeforeTakeInquiry.js +++ b/ee/app/livechat-enterprise/server/hooks/checkAgentBeforeTakeInquiry.js @@ -5,21 +5,21 @@ import { Users } from '../../../../../app/models/server/raw'; import { settings } from '../../../../../app/settings'; import { getMaxNumberSimultaneousChat } from '../lib/Helper'; import { allowAgentSkipQueue } from '../../../../../app/livechat/server/lib/Helper'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.checkAgentBeforeTakeInquiry', async ({ agent, inquiry, options }) => { if (!settings.get('Livechat_waiting_queue')) { - logger.cb.debug('Skipping callback. Disabled by setting'); + cbLogger.debug('Skipping callback. Disabled by setting'); return agent; } if (!inquiry || !agent) { - logger.cb.debug('Callback with error. No inquiry or agent provided'); + cbLogger.debug('Callback with error. No inquiry or agent provided'); return null; } if (allowAgentSkipQueue(agent)) { - logger.cb.debug(`Callback success. Agent ${ agent.agentId } can skip queue`); + cbLogger.debug(`Callback success. Agent ${ agent.agentId } can skip queue`); return agent; } @@ -28,19 +28,19 @@ callbacks.add('livechat.checkAgentBeforeTakeInquiry', async ({ agent, inquiry, o const maxNumberSimultaneousChat = getMaxNumberSimultaneousChat({ agentId, departmentId }); if (maxNumberSimultaneousChat === 0) { - logger.cb.debug(`Callback success. Agent ${ agentId } max number simultaneous chats on range`); + cbLogger.debug(`Callback success. Agent ${ agentId } max number simultaneous chats on range`); return agent; } const user = await Users.getAgentAndAmountOngoingChats(agentId); if (!user) { - logger.cb.debug('Callback with error. No valid agent found'); + cbLogger.debug('Callback with error. No valid agent found'); return null; } const { queueInfo: { chats = 0 } = {} } = user; if (maxNumberSimultaneousChat <= chats) { - logger.cb.debug('Callback with error. Agent reached max amount of simultaneous chats'); + cbLogger.debug('Callback with error. Agent reached max amount of simultaneous chats'); callbacks.run('livechat.onMaxNumberSimultaneousChatsReached', inquiry); if (options.clientAction && !options.forwardingToDepartment) { throw new Meteor.Error('error-max-number-simultaneous-chats-reached', 'Not allowed'); @@ -49,6 +49,6 @@ callbacks.add('livechat.checkAgentBeforeTakeInquiry', async ({ agent, inquiry, o return null; } - logger.cb.debug(`Callback success. Agent ${ agentId } can take inquiry ${ inquiry._id }`); + cbLogger.debug(`Callback success. Agent ${ agentId } can take inquiry ${ inquiry._id }`); return agent; }, callbacks.priority.MEDIUM, 'livechat-before-take-inquiry'); diff --git a/ee/app/livechat-enterprise/server/hooks/onAgentAssignmentFailed.ts b/ee/app/livechat-enterprise/server/hooks/onAgentAssignmentFailed.ts index a210b1354aa9..1defff8f75e1 100644 --- a/ee/app/livechat-enterprise/server/hooks/onAgentAssignmentFailed.ts +++ b/ee/app/livechat-enterprise/server/hooks/onAgentAssignmentFailed.ts @@ -2,16 +2,16 @@ import { callbacks } from '../../../../../app/callbacks/server'; import { LivechatInquiry, Subscriptions, LivechatRooms } from '../../../../../app/models/server'; import { queueInquiry } from '../../../../../app/livechat/server/lib/QueueManager'; import { settings } from '../../../../../app/settings/server'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; const handleOnAgentAssignmentFailed = async ({ inquiry, room, options }: { inquiry: any; room: any; options: { forwardingToDepartment?: { oldDepartmentId: string; transferData: any }; clientAction?: boolean} }): Promise => { if (!inquiry || !room) { - (logger as any).cb.debug('Skipping callback. No inquiry or room provided'); + cbLogger.debug('Skipping callback. No inquiry or room provided'); return; } if (room.onHold) { - (logger as any).cb.debug('Room is on hold. Removing current assignations before queueing again'); + cbLogger.debug('Room is on hold. Removing current assignations before queueing again'); const { _id: roomId } = room; const { _id: inquiryId } = inquiry; @@ -23,25 +23,25 @@ const handleOnAgentAssignmentFailed = async ({ inquiry, room, options }: { inqui await queueInquiry(room, newInquiry); - (logger as any).cb.debug('Room queued successfully'); + cbLogger.debug('Room queued successfully'); return; } if (!settings.get('Livechat_waiting_queue')) { - (logger as any).cb.debug('Skipping callback. Queue disabled by setting'); + cbLogger.debug('Skipping callback. Queue disabled by setting'); return; } const { forwardingToDepartment: { oldDepartmentId } = {}, forwardingToDepartment } = options; if (!forwardingToDepartment) { - (logger as any).cb.debug('Skipping callback. Room not being forwarded to department'); + cbLogger.debug('Skipping callback. Room not being forwarded to department'); return; } const { department: newDepartmentId } = inquiry; if (!newDepartmentId || !oldDepartmentId || newDepartmentId === oldDepartmentId) { - (logger as any).cb.debug('Skipping callback. New and old departments are the same'); + cbLogger.debug('Skipping callback. New and old departments are the same'); return; } diff --git a/ee/app/livechat-enterprise/server/hooks/onLoadForwardDepartmentRestrictions.js b/ee/app/livechat-enterprise/server/hooks/onLoadForwardDepartmentRestrictions.js index b3cf0946c7c3..7f0daf66505c 100644 --- a/ee/app/livechat-enterprise/server/hooks/onLoadForwardDepartmentRestrictions.js +++ b/ee/app/livechat-enterprise/server/hooks/onLoadForwardDepartmentRestrictions.js @@ -1,21 +1,21 @@ import { callbacks } from '../../../../../app/callbacks'; import { LivechatDepartment } from '../../../../../app/models/server'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; callbacks.add('livechat.onLoadForwardDepartmentRestrictions', (options = {}) => { const { departmentId } = options; if (!departmentId) { - logger.cb.debug('Skipping callback. No departmentId provided'); + cbLogger.debug('Skipping callback. No departmentId provided'); return options; } const department = LivechatDepartment.findOneById(departmentId, { fields: { departmentsAllowedToForward: 1 } }); if (!department) { - logger.cb.debug('Skipping callback. Invalid department provided'); + cbLogger.debug('Skipping callback. Invalid department provided'); return options; } const { departmentsAllowedToForward, _id } = department; if (!departmentsAllowedToForward) { - logger.cb.debug(`Skipping callback. Department ${ _id } doesnt allow forwarding to other departments`); + cbLogger.debug(`Skipping callback. Department ${ _id } doesnt allow forwarding to other departments`); return options; } return Object.assign({ restrictions: { _id: { $in: departmentsAllowedToForward } } }, options); diff --git a/ee/app/livechat-enterprise/server/hooks/scheduleAutoTransfer.ts b/ee/app/livechat-enterprise/server/hooks/scheduleAutoTransfer.ts index 4ba6d8fcd277..516452c5cc05 100644 --- a/ee/app/livechat-enterprise/server/hooks/scheduleAutoTransfer.ts +++ b/ee/app/livechat-enterprise/server/hooks/scheduleAutoTransfer.ts @@ -2,29 +2,29 @@ import { AutoTransferChatScheduler } from '../lib/AutoTransferChatScheduler'; import { callbacks } from '../../../../../app/callbacks/server'; import { settings } from '../../../../../app/settings/server'; import { LivechatRooms } from '../../../../../app/models/server'; -import { logger } from '../lib/logger'; +import { cbLogger } from '../lib/logger'; let autoTransferTimeout = 0; const handleAfterTakeInquiryCallback = async (inquiry: any = {}): Promise => { const { rid } = inquiry; if (!rid || !rid.trim()) { - (logger as any).cb.debug('Skipping callback. Invalid room id'); + cbLogger.debug('Skipping callback. Invalid room id'); return; } if (!autoTransferTimeout || autoTransferTimeout <= 0) { - (logger as any).cb.debug('Skipping callback. No auto transfer timeout or invalid value from setting'); + cbLogger.debug('Skipping callback. No auto transfer timeout or invalid value from setting'); return inquiry; } const room = LivechatRooms.findOneById(rid, { autoTransferredAt: 1, autoTransferOngoing: 1 }); if (!room || room.autoTransferredAt || room.autoTransferOngoing) { - (logger as any).cb.debug(`Skipping callback. Room ${ room._id } already being transfered or not found`); + cbLogger.debug(`Skipping callback. Room ${ room._id } already being transfered or not found`); return inquiry; } - (logger as any).cb.debug(`Callback success. Room ${ room._id } will be scheduled to be auto transfered after ${ autoTransferTimeout } seconds`); + cbLogger.debug(`Callback success. Room ${ room._id } will be scheduled to be auto transfered after ${ autoTransferTimeout } seconds`); await AutoTransferChatScheduler.scheduleRoom(rid, autoTransferTimeout as number); return inquiry; diff --git a/ee/app/livechat-enterprise/server/lib/Helper.js b/ee/app/livechat-enterprise/server/lib/Helper.js index 96ac410c2d49..6aec9f3553eb 100644 --- a/ee/app/livechat-enterprise/server/lib/Helper.js +++ b/ee/app/livechat-enterprise/server/lib/Helper.js @@ -14,7 +14,7 @@ import { settings } from '../../../../../app/settings'; import { RoutingManager } from '../../../../../app/livechat/server/lib/RoutingManager'; import { dispatchAgentDelegated } from '../../../../../app/livechat/server/lib/Helper'; import notifications from '../../../../../app/notifications/server/lib/Notifications'; -import { logger } from './logger'; +import { logger, helperLogger } from './logger'; export const getMaxNumberSimultaneousChat = ({ agentId, departmentId }) => { if (departmentId) { @@ -93,7 +93,7 @@ export const dispatchInquiryPosition = async (inquiry, queueInfo) => { }; export const dispatchWaitingQueueStatus = async (department) => { - logger.helper.debug(`Updating statuses for queue ${ department || 'Public' }`); + helperLogger.debug(`Updating statuses for queue ${ department || 'Public' }`); const queue = await LivechatInquiry.getCurrentSortedQueueAsync({ department }); const queueInfo = await getQueueInfo(department); queue.forEach((inquiry) => { @@ -103,14 +103,14 @@ export const dispatchWaitingQueueStatus = async (department) => { export const processWaitingQueue = async (department) => { const queue = department || 'Public'; - logger.helper.debug(`Processing items on queue ${ queue }`); + helperLogger.debug(`Processing items on queue ${ queue }`); const inquiry = LivechatInquiry.getNextInquiryQueued(department); if (!inquiry) { - logger.helper.debug(`No items to process on queue ${ queue }`); + helperLogger.debug(`No items to process on queue ${ queue }`); return; } - logger.helper.debug(`Processing inquiry ${ inquiry._id } from queue ${ queue }`); + helperLogger.debug(`Processing inquiry ${ inquiry._id } from queue ${ queue }`); const { defaultAgent } = inquiry; const room = await RoutingManager.delegateInquiry(inquiry, defaultAgent); @@ -120,7 +120,7 @@ export const processWaitingQueue = async (department) => { if (room && room.servedBy) { const { _id: rid, servedBy: { _id: agentId } } = room; - logger.helper.debug(`Inquiry ${ inquiry._id } taken succesfully by agent ${ agentId }. Notifying`); + helperLogger.debug(`Inquiry ${ inquiry._id } taken succesfully by agent ${ agentId }. Notifying`); return setTimeout(() => { propagateAgentDelegated(rid, agentId); }, 1000); diff --git a/ee/app/livechat-enterprise/server/lib/LivechatEnterprise.js b/ee/app/livechat-enterprise/server/lib/LivechatEnterprise.js index 20729ccc5008..d8de93eb4fa9 100644 --- a/ee/app/livechat-enterprise/server/lib/LivechatEnterprise.js +++ b/ee/app/livechat-enterprise/server/lib/LivechatEnterprise.js @@ -11,7 +11,7 @@ import { addUserRoles, removeUserFromRoles } from '../../../../../app/authorizat import { processWaitingQueue, removePriorityFromRooms, updateInquiryQueuePriority, updatePriorityInquiries, updateRoomPriorityHistory } from './Helper'; import { RoutingManager } from '../../../../../app/livechat/server/lib/RoutingManager'; import { settings } from '../../../../../app/settings/server'; -import { logger } from './logger'; +import { logger, queueLogger } from './logger'; import { callbacks } from '../../../../../app/callbacks'; import { AutoCloseOnHoldScheduler } from './AutoCloseOnHoldScheduler'; @@ -205,21 +205,21 @@ const queueWorker = { running: false, queues: [], async start() { - logger.queue.debug('Starting queue'); + queueLogger.debug('Starting queue'); if (this.running) { - logger.queue.debug('Queue already running'); + queueLogger.debug('Queue already running'); return; } const activeQueues = await this.getActiveQueues(); - logger.queue.debug(`Active queues: ${ activeQueues.length }`); + queueLogger.debug(`Active queues: ${ activeQueues.length }`); await OmnichannelQueue.initQueue(); this.running = true; return this.execute(); }, async stop() { - logger.queue.debug('Stopping queue'); + queueLogger.debug('Stopping queue'); this.running = false; return OmnichannelQueue.stopQueue(); }, @@ -229,7 +229,7 @@ const queueWorker = { }, async nextQueue() { if (!this.queues.length) { - logger.queue.debug('No more registered queues. Refreshing'); + queueLogger.debug('No more registered queues. Refreshing'); this.queues = await this.getActiveQueues(); } @@ -237,21 +237,21 @@ const queueWorker = { }, async execute() { if (!this.running) { - logger.queue.debug('Queue stopped. Cannot execute'); + queueLogger.debug('Queue stopped. Cannot execute'); return; } const queue = await this.nextQueue(); - logger.queue.debug(`Executing queue ${ queue || 'Public' } with timeout of ${ RACE_TIMEOUT }`); + queueLogger.debug(`Executing queue ${ queue || 'Public' } with timeout of ${ RACE_TIMEOUT }`); setTimeout(this.checkQueue.bind(this, queue), RACE_TIMEOUT); }, async checkQueue(queue) { - logger.queue.debug(`Processing items for queue ${ queue || 'Public' }`); + queueLogger.debug(`Processing items for queue ${ queue || 'Public' }`); if (await OmnichannelQueue.lockQueue()) { await processWaitingQueue(queue); - logger.queue.debug(`Queue ${ queue || 'Public' } processed. Unlocking`); + queueLogger.debug(`Queue ${ queue || 'Public' } processed. Unlocking`); await OmnichannelQueue.unlockQueue(); } @@ -261,7 +261,7 @@ const queueWorker = { settings.onload('Livechat_Routing_Method', function() { const routingSupportsAutoAssign = RoutingManager.getConfig().autoAssignAgent; - logger.queue.debug(`Routing method ${ RoutingManager.methodName } supports auto assignment: ${ routingSupportsAutoAssign }. ${ + queueLogger.debug(`Routing method ${ RoutingManager.methodName } supports auto assignment: ${ routingSupportsAutoAssign }. ${ routingSupportsAutoAssign ? 'Starting' : 'Stopping' diff --git a/ee/app/livechat-enterprise/server/lib/logger.js b/ee/app/livechat-enterprise/server/lib/logger.js index 51a4a7275e00..85a72ad6858c 100644 --- a/ee/app/livechat-enterprise/server/lib/logger.js +++ b/ee/app/livechat-enterprise/server/lib/logger.js @@ -1,10 +1,8 @@ -import { Logger } from '../../../../../app/logger/server/server'; +import { Logger } from '../../../../../app/logger/server'; -export const logger = new Logger('LivechatEnterprise', { - sections: { - queries: 'Queries', - queue: 'Queue', - helper: 'Helper', - cb: 'Callbacks', - }, -}); +export const logger = new Logger('LivechatEnterprise'); + +export const queriesLogger = logger.section('Queries'); +export const queueLogger = logger.section('Queue'); +export const helperLogger = logger.section('Helper'); +export const cbLogger = logger.section('Callbacks'); diff --git a/ee/app/models/server/models/LivechatRooms.js b/ee/app/models/server/models/LivechatRooms.js index 36517ab86747..7b23bc5f5f34 100644 --- a/ee/app/models/server/models/LivechatRooms.js +++ b/ee/app/models/server/models/LivechatRooms.js @@ -1,11 +1,11 @@ import { LivechatRooms } from '../../../../../app/models/server/models/LivechatRooms'; -import { logger } from '../../../livechat-enterprise/server/lib/logger'; +import { queriesLogger } from '../../../livechat-enterprise/server/lib/logger'; import { addQueryRestrictionsToRoomsModel } from '../../../livechat-enterprise/server/lib/query.helper'; import { overwriteClassOnLicense } from '../../../license/server'; const applyRestrictions = (method) => function(originalFn, originalQuery, ...args) { const query = addQueryRestrictionsToRoomsModel(originalQuery); - logger.queries.debug(() => `LivechatRooms.${ method } - ${ JSON.stringify(query) }`); + queriesLogger.debug({ msg: `LivechatRooms.${ method }`, query }); return originalFn.call(this, query, ...args); }; diff --git a/ee/app/models/server/models/LivechatUnit.js b/ee/app/models/server/models/LivechatUnit.js index a36f0d54b7fd..5c689219421d 100644 --- a/ee/app/models/server/models/LivechatUnit.js +++ b/ee/app/models/server/models/LivechatUnit.js @@ -2,7 +2,7 @@ import _ from 'underscore'; import LivechatDepartmentInstance, { LivechatDepartment } from '../../../../../app/models/server/models/LivechatDepartment'; import { getUnitsFromUser } from '../../../livechat-enterprise/server/lib/units'; -import { logger } from '../../../livechat-enterprise/server/lib/logger'; +import { queriesLogger } from '../../../livechat-enterprise/server/lib/logger'; import LivechatUnitMonitors from './LivechatUnitMonitors'; const addQueryRestrictions = (originalQuery = {}) => { @@ -23,13 +23,13 @@ const addQueryRestrictions = (originalQuery = {}) => { export class LivechatUnit extends LivechatDepartment { find(originalQuery, ...args) { const query = addQueryRestrictions(originalQuery); - logger.queries.debug('LivechatUnit.find', JSON.stringify(query)); + queriesLogger.debug({ msg: 'LivechatUnit.find', query }); return this.unfilteredFind(query, ...args); } findOne(originalQuery, ...args) { const query = addQueryRestrictions(originalQuery); - logger.queries.debug('LivechatUnit.findOne', JSON.stringify(query)); + queriesLogger.debug({ msg: 'LivechatUnit.findOne', query }); return super.unfilteredFindOne(query, ...args); } diff --git a/ee/app/models/server/raw/LivechatRooms.js b/ee/app/models/server/raw/LivechatRooms.js index afc085309c12..caba2b2c3c85 100644 --- a/ee/app/models/server/raw/LivechatRooms.js +++ b/ee/app/models/server/raw/LivechatRooms.js @@ -1,11 +1,11 @@ import { LivechatRoomsRaw } from '../../../../../app/models/server/raw/LivechatRooms'; -import { logger } from '../../../livechat-enterprise/server/lib/logger'; +import { queriesLogger } from '../../../livechat-enterprise/server/lib/logger'; import { addQueryRestrictionsToRoomsModel } from '../../../livechat-enterprise/server/lib/query.helper'; import { overwriteClassOnLicense } from '../../../license/server'; const applyRestrictions = (method) => function(originalFn, originalQuery, ...args) { const query = addQueryRestrictionsToRoomsModel(originalQuery); - logger.queries.debug(() => `LivechatRoomsRaw.${ method } - ${ JSON.stringify(query) }`); + queriesLogger.debug({ msg: `LivechatRoomsRaw.${ method }`, query }); return originalFn.call(this, query, ...args); }; diff --git a/ee/server/services/ecdh-proxy/lib/server.ts b/ee/server/services/ecdh-proxy/lib/server.ts index cee61da95ed9..a17a812e2c8e 100644 --- a/ee/server/services/ecdh-proxy/lib/server.ts +++ b/ee/server/services/ecdh-proxy/lib/server.ts @@ -117,7 +117,7 @@ app.post('/api/ecdh_proxy/echo', async (req, res) => { const result = await session.decrypt(req.body.text); res.send(await session.encrypt(result)); } catch (e) { - console.log(e); + console.error(e); res.status(400).send(e.message); } }); @@ -129,7 +129,7 @@ const httpServer = app.listen(port, () => { const wss = new WebSocket.Server({ server: httpServer }); wss.on('error', (error) => { - console.log(error); + console.error(error); }); wss.on('connection', async (ws, req) => { diff --git a/ee/server/services/package-lock.json b/ee/server/services/package-lock.json index 215e0b930757..dfa50a427aa6 100644 --- a/ee/server/services/package-lock.json +++ b/ee/server/services/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@hapi/bourne": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", + "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==", + "dev": true + }, "@mapbox/node-pre-gyp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", @@ -595,6 +601,11 @@ } } }, + "atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" + }, "axios": { "version": "0.21.4", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", @@ -840,6 +851,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colorette": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==" + }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", @@ -944,6 +960,12 @@ "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", "dev": true }, + "dateformat": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.5.1.tgz", + "integrity": "sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q==", + "dev": true + }, "dayjs": { "version": "1.8.36", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", @@ -1030,6 +1052,15 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -1184,6 +1215,16 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fast-redact": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.0.1.tgz", + "integrity": "sha512-kYpn4Y/valC9MdrISg47tZOpYBNoTXKgT9GYXFpHN/jYFs+lFkPoisY+LcBODdKVMY96ATzvzsWv+ES/4Kmufw==" + }, + "fast-safe-stringify": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz", + "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==" + }, "fastest-validator": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/fastest-validator/-/fastest-validator-1.11.0.tgz", @@ -1348,6 +1389,11 @@ "wide-align": "^1.1.0" } }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, "get-uri": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", @@ -1584,6 +1630,18 @@ } } }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "dev": true + }, + "joycon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.0.1.tgz", + "integrity": "sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA==", + "dev": true + }, "js-git": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", @@ -1599,9 +1657,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true, - "optional": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "jsonfile": { "version": "4.0.0", @@ -2029,6 +2085,11 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "on-exit-leak-free": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz", + "integrity": "sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==" + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -2144,6 +2205,69 @@ "safe-buffer": "^5.2.1" } }, + "pino": { + "version": "7.0.0-rc.3", + "resolved": "https://registry.npmjs.org/pino/-/pino-7.0.0-rc.3.tgz", + "integrity": "sha512-klo/nmCwlwYixe9y9ke8n9VkAXQX/de8tUBcpZb9AUWNsb5gfs8A5d8WhKKjFW2gSp8GO3gUi4HiREw6cTyXXA==", + "requires": { + "fast-redact": "^3.0.0", + "fast-safe-stringify": "^2.0.8", + "get-caller-file": "^2.0.5", + "json-stringify-safe": "^5.0.1", + "on-exit-leak-free": "^0.2.0", + "pino-abstract-transport": "^0.2.0", + "pino-std-serializers": "^4.0.0", + "quick-format-unescaped": "^4.0.3", + "sonic-boom": "^2.1.0", + "thread-stream": "^0.11.0" + } + }, + "pino-abstract-transport": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.2.0.tgz", + "integrity": "sha512-40sX7xrzDXsrUYr65brL0+bLm6rpZ+wCujDeeBmmZ/y5RVcPdVQsmz0bBe8NtTpELgmzmKwRRPVj1lvKjgFVHw==", + "requires": { + "split2": "^3.2.2" + } + }, + "pino-pretty": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-6.0.0.tgz", + "integrity": "sha512-jyeR2fXXWc68st1DTTM5NhkHlx8p+1fKZMfm84Jwq+jSw08IwAjNaZBZR6ts69hhPOfOjg/NiE1HYW7vBRPL3A==", + "dev": true, + "requires": { + "@hapi/bourne": "^2.0.0", + "args": "^5.0.1", + "colorette": "^1.3.0", + "dateformat": "^4.5.1", + "fast-safe-stringify": "^2.0.7", + "jmespath": "^0.15.0", + "joycon": "^3.0.0", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "rfdc": "^1.3.0", + "split2": "^3.1.1", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "pino-std-serializers": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz", + "integrity": "sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==" + }, "pm2": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.1.1.tgz", @@ -2315,11 +2439,26 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "quick-format-unescaped": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz", + "integrity": "sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg==" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -2405,6 +2544,12 @@ "path-parse": "^1.0.6" } }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2592,6 +2737,14 @@ "xsalsa20": "^1.1.0" } }, + "sonic-boom": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.1.0.tgz", + "integrity": "sha512-x2j9LXx27EDlyZEC32gBM+scNVMdPutU7FIKV2BOTKCnPrp7bY5BsplCMQ4shYYR3IhDSIrEXoqb6GlS+z7KyQ==", + "requires": { + "atomic-sleep": "^1.0.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2617,6 +2770,26 @@ "memory-pager": "^1.0.2" } }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", @@ -2665,6 +2838,12 @@ "ansi-regex": "^2.0.0" } }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2701,6 +2880,11 @@ } } }, + "thread-stream": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-0.11.0.tgz", + "integrity": "sha512-uzfig6tGx9SpdZSkkp++gLQnd7S7RDOQkZM8OiURY4E2ZsnanrAHQKc8z9lOlAqO4KBHh+KXU8+oZUOhFG9zbQ==" + }, "thriftrw": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/thriftrw/-/thriftrw-3.12.0.tgz", diff --git a/ee/server/services/package.json b/ee/server/services/package.json index bf9577e5369b..07e2e29385ff 100644 --- a/ee/server/services/package.json +++ b/ee/server/services/package.json @@ -21,6 +21,7 @@ "@rocket.chat/string-helpers": "^0.27.0", "bcrypt": "^5.0.1", "body-parser": "^1.19.0", + "colorette": "^1.3.0", "cookie": "^0.4.1", "cookie-parser": "^1.4.5", "ejson": "^2.2.1", @@ -31,6 +32,7 @@ "moleculer": "^0.14.14", "mongodb": "^3.6.9", "nats": "^1.4.12", + "pino": "^7.0.0-rc.3", "sodium-native": "^3.2.1", "sodium-plus": "^0.9.0", "underscore.string": "^3.3.5", @@ -45,6 +47,7 @@ "@types/mongodb": "^3.6.19", "@types/node": "^14.17.4", "@types/ws": "^7.4.7", + "pino-pretty": "^6.0.0", "pm2": "^5.1.1", "ts-node": "^10.0.0", "typescript": "^4.3.5" diff --git a/imports/message-read-receipt/server/lib/ReadReceipt.js b/imports/message-read-receipt/server/lib/ReadReceipt.js index d9212e389672..ab30a835763b 100644 --- a/imports/message-read-receipt/server/lib/ReadReceipt.js +++ b/imports/message-read-receipt/server/lib/ReadReceipt.js @@ -4,6 +4,7 @@ import { Random } from 'meteor/random'; import { ReadReceipts, Subscriptions, Messages, Rooms, Users, LivechatVisitors } from '../../../../app/models'; import { settings } from '../../../../app/settings'; import { roomTypes } from '../../../../app/utils'; +import { SystemLogger } from '../../../../server/lib/logger/system'; const rawReadReceipts = ReadReceipts.model.rawCollection(); @@ -86,7 +87,7 @@ export const ReadReceipt = { try { await rawReadReceipts.insertMany(receipts); } catch (e) { - console.error('Error inserting read receipts per user'); + SystemLogger.error('Error inserting read receipts per user'); } } }, diff --git a/package-lock.json b/package-lock.json index a17f1185612d..b28bab4daa91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3952,6 +3952,12 @@ "protobufjs": "^6.8.6" } }, + "@hapi/bourne": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", + "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==", + "dev": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -12009,6 +12015,11 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" + }, "autolinker": { "version": "3.14.3", "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.14.3.tgz", @@ -15563,9 +15574,9 @@ } }, "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==" }, "colors": { "version": "1.4.0", @@ -16800,6 +16811,12 @@ } } }, + "dateformat": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.5.1.tgz", + "integrity": "sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q==", + "dev": true + }, "dayjs": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.5.tgz", @@ -19049,6 +19066,11 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fast-redact": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.0.1.tgz", + "integrity": "sha512-kYpn4Y/valC9MdrISg47tZOpYBNoTXKgT9GYXFpHN/jYFs+lFkPoisY+LcBODdKVMY96ATzvzsWv+ES/4Kmufw==" + }, "fast-safe-stringify": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", @@ -21045,8 +21067,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-css-data": { "version": "2.0.2", @@ -23597,6 +23618,12 @@ "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" }, + "joycon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.0.1.tgz", + "integrity": "sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA==", + "dev": true + }, "jquery": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", @@ -28404,6 +28431,11 @@ "integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==", "dev": true }, + "on-exit-leak-free": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz", + "integrity": "sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==" + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -28901,6 +28933,92 @@ "pinkie": "^2.0.0" } }, + "pino": { + "version": "7.0.0-rc.3", + "resolved": "https://registry.npmjs.org/pino/-/pino-7.0.0-rc.3.tgz", + "integrity": "sha512-klo/nmCwlwYixe9y9ke8n9VkAXQX/de8tUBcpZb9AUWNsb5gfs8A5d8WhKKjFW2gSp8GO3gUi4HiREw6cTyXXA==", + "requires": { + "fast-redact": "^3.0.0", + "fast-safe-stringify": "^2.0.8", + "get-caller-file": "^2.0.5", + "json-stringify-safe": "^5.0.1", + "on-exit-leak-free": "^0.2.0", + "pino-abstract-transport": "^0.2.0", + "pino-std-serializers": "^4.0.0", + "quick-format-unescaped": "^4.0.3", + "sonic-boom": "^2.1.0", + "thread-stream": "^0.11.0" + }, + "dependencies": { + "fast-safe-stringify": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz", + "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==" + } + } + }, + "pino-abstract-transport": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.2.0.tgz", + "integrity": "sha512-40sX7xrzDXsrUYr65brL0+bLm6rpZ+wCujDeeBmmZ/y5RVcPdVQsmz0bBe8NtTpELgmzmKwRRPVj1lvKjgFVHw==", + "requires": { + "split2": "^3.2.2" + } + }, + "pino-pretty": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-6.0.0.tgz", + "integrity": "sha512-jyeR2fXXWc68st1DTTM5NhkHlx8p+1fKZMfm84Jwq+jSw08IwAjNaZBZR6ts69hhPOfOjg/NiE1HYW7vBRPL3A==", + "dev": true, + "requires": { + "@hapi/bourne": "^2.0.0", + "args": "^5.0.1", + "colorette": "^1.3.0", + "dateformat": "^4.5.1", + "fast-safe-stringify": "^2.0.7", + "jmespath": "^0.15.0", + "joycon": "^3.0.0", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "rfdc": "^1.3.0", + "split2": "^3.1.1", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } + } + }, + "pino-std-serializers": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz", + "integrity": "sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==" + }, "pinyin": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/pinyin/-/pinyin-2.9.1.tgz", @@ -30955,6 +31073,11 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "quick-format-unescaped": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz", + "integrity": "sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg==" + }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -32578,6 +32701,12 @@ "eslint": "^6.8.0" } }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -33285,6 +33414,14 @@ "xsalsa20": "^1.1.0" } }, + "sonic-boom": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.1.0.tgz", + "integrity": "sha512-x2j9LXx27EDlyZEC32gBM+scNVMdPutU7FIKV2BOTKCnPrp7bY5BsplCMQ4shYYR3IhDSIrEXoqb6GlS+z7KyQ==", + "requires": { + "atomic-sleep": "^1.0.0" + } + }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -33415,6 +33552,26 @@ "extend-shallow": "^3.0.0" } }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "sprintf-js": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", @@ -35421,6 +35578,11 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "thread-stream": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-0.11.0.tgz", + "integrity": "sha512-uzfig6tGx9SpdZSkkp++gLQnd7S7RDOQkZM8OiURY4E2ZsnanrAHQKc8z9lOlAqO4KBHh+KXU8+oZUOhFG9zbQ==" + }, "throttle-debounce": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", diff --git a/package.json b/package.json index a32b54d63747..6f310875d1d4 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,7 @@ "mocha": "^9.0.0", "mock-require": "^3.0.3", "mongo-unit": "^2.0.1", + "pino-pretty": "^6.0.0", "postcss": "^8.3.5", "postcss-custom-properties": "^11.0.0", "postcss-easy-import": "^3.0.0", @@ -194,6 +195,7 @@ "chart.js": "^2.9.3", "clipboard": "^2.0.8", "codemirror": "^5.62.0", + "colorette": "^1.3.0", "connect": "^3.7.0", "cors": "^2.8.5", "csv-parse": "^4.16.3", @@ -254,6 +256,7 @@ "object-path": "^0.11.6", "pdfjs-dist": "^2.8.335", "photoswipe": "^4.1.3", + "pino": "^7.0.0-rc.3", "poplib": "^0.1.7", "postis": "^2.2.0", "prom-client": "^12.0.0", diff --git a/server/features/EmailInbox/EmailInbox_Incoming.ts b/server/features/EmailInbox/EmailInbox_Incoming.ts index 7ceaff1921ab..e4b21121eda7 100644 --- a/server/features/EmailInbox/EmailInbox_Incoming.ts +++ b/server/features/EmailInbox/EmailInbox_Incoming.ts @@ -187,7 +187,7 @@ export async function onEmailReceived(email: ParsedMail, inbox: string, departme try { attachments.push(await uploadAttachment(attachment, rid, guest.token)); } catch (e) { - console.error('Error uploading attachment from email', e); + Livechat.logger.error('Error uploading attachment from email', e); } } @@ -199,6 +199,6 @@ export async function onEmailReceived(email: ParsedMail, inbox: string, departme }, }); }).catch((error) => { - console.log('Error receiving Email: %s', error.message); + Livechat.logger.log('Error receiving Email: %s', error.message); }); } diff --git a/server/lib/logger/Logger.ts b/server/lib/logger/Logger.ts new file mode 100644 index 000000000000..619f17b7ece2 --- /dev/null +++ b/server/lib/logger/Logger.ts @@ -0,0 +1,97 @@ +import type { P } from 'pino'; + +import { getPino } from './getPino'; +import { logLevel, LogLevelSetting } from './logLevel'; + +const getLevel = (level: LogLevelSetting): string => { + switch (level) { + case '0': return 'warn'; + case '1': return 'info'; + case '2': return 'debug'; + default: return 'warn'; + } +}; + +export class Logger { + readonly logger: P.Logger; + + constructor(loggerLabel: string) { + this.logger = getPino(loggerLabel); + + logLevel.on('changed', (level) => { + this.logger.level = getLevel(level); + }); + } + + section(name: string): P.Logger { + return this.logger.child({ section: name }); + } + + level(newLevel: string): void { + this.logger.level = newLevel; + } + + log(obj: T, ...args: any[]): void; + + log(msg: string, ...args: any[]): void; + + log(msg: string, ...args: any[]): void { + this.logger.info(msg, ...args); + } + + debug(obj: T, ...args: any[]): void; + + debug(msg: string, ...args: any[]): void; + + debug(msg: string, ...args: any[]): void { + this.logger.debug(msg, ...args); + } + + info(obj: T, ...args: any[]): void; + + info(msg: string, ...args: any[]): void; + + info(msg: string, ...args: any[]): void { + this.logger.info(msg, ...args); + } + + success(obj: T, ...args: any[]): void; + + success(msg: string, ...args: any[]): void; + + success(msg: string, ...args: any[]): void { + this.logger.info(msg, ...args); + } + + warn(obj: T, ...args: any[]): void; + + warn(msg: string, ...args: any[]): void; + + warn(msg: string, ...args: any[]): void { + this.logger.warn(msg, ...args); + } + + error(obj: T, ...args: any[]): void; + + error(msg: string, ...args: any[]): void; + + error(msg: string, ...args: any[]): void { + this.logger.error(msg, ...args); + } + + method(obj: T, ...args: any[]): void; + + method(msg: string, ...args: any[]): void; + + method(msg: string, ...args: any[]): void { + this.logger.method(msg, ...args); + } + + subscription(obj: T, ...args: any[]): void; + + subscription(msg: string, ...args: any[]): void; + + subscription(msg: string, ...args: any[]): void { + this.logger.subscription(msg, ...args); + } +} diff --git a/server/lib/logger/getPino.ts b/server/lib/logger/getPino.ts new file mode 100644 index 000000000000..37f02f019574 --- /dev/null +++ b/server/lib/logger/getPino.ts @@ -0,0 +1,25 @@ +import { pino } from 'pino'; +import type { P } from 'pino'; + +// add support to multiple params on the log commands, i.e.: +// logger.info('user', Meteor.user()); // will print: {"level":30,"time":1629814080968,"msg":"user {\"username\": \"foo\"}"} +function logMethod(this: P.Logger, args: unknown[], method: any): void { + if (args.length > 1) { + args[0] = `${ args[0] }${ ' %j'.repeat(args.length - 1) }`; + } + return method.apply(this, args); +} + +export function getPino(name: string): P.Logger { + return pino({ + name, + hooks: { logMethod }, + customLevels: { + http: 35, + method: 35, + subscription: 35, + }, + timestamp: pino.stdTimeFunctions.isoTime, + ...process.env.NODE_ENV !== 'production' ? { prettyPrint: { colorize: true } } : {}, + }); +} diff --git a/server/lib/logger/logLevel.ts b/server/lib/logger/logLevel.ts new file mode 100644 index 000000000000..ff0239c84525 --- /dev/null +++ b/server/lib/logger/logLevel.ts @@ -0,0 +1,7 @@ +import { Emitter } from '@rocket.chat/emitter'; + +export type LogLevelSetting = '0' | '1' | '2'; + +export const logLevel = new Emitter<{ + changed: LogLevelSetting; +}>(); diff --git a/server/lib/logger/logPayloads.ts b/server/lib/logger/logPayloads.ts new file mode 100644 index 000000000000..7b3ad8270417 --- /dev/null +++ b/server/lib/logger/logPayloads.ts @@ -0,0 +1,33 @@ +import _ from 'underscore'; + +const { + LOG_METHOD_PAYLOAD = 'false', + LOG_REST_PAYLOAD = 'false', + LOG_REST_METHOD_PAYLOADS = 'false', +} = process.env; + +export const getMethodArgs = LOG_METHOD_PAYLOAD === 'false' && LOG_REST_METHOD_PAYLOADS === 'false' + ? (): null => null + : (method: string, args: any[]): { arguments: any } => { + const params = method === 'ufsWrite' ? args.slice(1) : args; + + if (method === 'saveSettings') { + return { arguments: [args[0].map((arg: any) => _.omit(arg, 'value'))] }; + } + + if (method === 'saveSetting') { + return { arguments: [args[0], args[2]] }; + } + + return { + arguments: params.map((arg) => (typeof arg !== 'object' + ? arg + : _.omit(arg, 'password', 'msg', 'pass', 'username', 'message'))), + }; + }; + +export const getRestPayload = LOG_REST_PAYLOAD === 'false' && LOG_REST_METHOD_PAYLOADS === 'false' + ? (): null => null + : (payload: unknown): { payload: unknown } => ({ + payload, + }); diff --git a/server/lib/logger/showBox.ts b/server/lib/logger/showBox.ts new file mode 100644 index 000000000000..1384a6b8c75f --- /dev/null +++ b/server/lib/logger/showBox.ts @@ -0,0 +1,42 @@ +import s from 'underscore.string'; +import * as colors from 'colorette'; + +// force enable colors on dev env +if (process.env.NODE_ENV !== 'production') { + colors.options.enabled = true; +} + +type LogColors = 'white' | 'blue' | 'green' | 'magenta' | 'red'; + +export function showBox(title: string, message: string, color?: LogColors): void { + const msgLines = message.split('\n'); + + const len = Math.max.apply(null, msgLines.map((line) => line.length)); + + const topLine = `+--${ s.pad('', len, '-') }--+`; + const separator = `| ${ s.pad('', len, '') } |`; + + const lines = []; + + lines.push(topLine); + if (title) { + lines.push(`| ${ s.lrpad(title, len) } |`); + lines.push(topLine); + } + lines.push(separator); + + [...lines, ...msgLines.map((line) => `| ${ s.rpad(line, len) } |`), separator, topLine] + .forEach((line) => console.log(color ? colors[color](line) : line)); +} + +export function showErrorBox(title: string, message: string): void { + showBox(title, message, 'red'); +} + +export function showSuccessBox(title: string, message: string): void { + showBox(title, message, 'green'); +} + +export function showWarningBox(title: string, message: string): void { + showBox(title, message, 'magenta'); +} diff --git a/server/lib/logger/startup.ts b/server/lib/logger/startup.ts new file mode 100644 index 000000000000..1b9c1cd0e8e5 --- /dev/null +++ b/server/lib/logger/startup.ts @@ -0,0 +1,8 @@ +import { settings } from '../../../app/settings/server'; +import { logLevel, LogLevelSetting } from './logLevel'; + +settings.get('Log_Level', (_key, value) => { + if (value != null) { + logLevel.emit('changed', String(value) as LogLevelSetting); + } +}); diff --git a/server/lib/logger/system.ts b/server/lib/logger/system.ts new file mode 100644 index 000000000000..7e1641faee81 --- /dev/null +++ b/server/lib/logger/system.ts @@ -0,0 +1,3 @@ +import { Logger } from './Logger'; + +export const SystemLogger = new Logger('System'); diff --git a/server/lib/sendMessagesToAdmins.js b/server/lib/sendMessagesToAdmins.js index 075fc2e14380..5eedbf14aeae 100644 --- a/server/lib/sendMessagesToAdmins.js +++ b/server/lib/sendMessagesToAdmins.js @@ -1,5 +1,6 @@ import { Meteor } from 'meteor/meteor'; +import { SystemLogger } from './logger/system'; import { Roles, Users } from '../../app/models/server'; export function sendMessagesToAdmins({ @@ -37,7 +38,7 @@ export function sendMessagesToAdmins({ msgs.forEach((msg) => Meteor.call('sendMessage', Object.assign({ rid }, msg))); }); } catch (e) { - console.error(e); + SystemLogger.error(e); } } diff --git a/server/main.js b/server/main.js index c6de4a2f91d4..7a37123b9f26 100644 --- a/server/main.js +++ b/server/main.js @@ -5,6 +5,7 @@ import '../imports/startup/server'; import './services/startup'; import '../ee/server'; +import './lib/logger/startup'; import './lib/pushConfig'; import './startup/migrations'; import './startup/appcache'; diff --git a/server/methods/sendForgotPasswordEmail.js b/server/methods/sendForgotPasswordEmail.js index a17931918b59..bb8d5ea56ada 100644 --- a/server/methods/sendForgotPasswordEmail.js +++ b/server/methods/sendForgotPasswordEmail.js @@ -4,6 +4,7 @@ import { Accounts } from 'meteor/accounts-base'; import { Users } from '../../app/models'; import { settings } from '../../app/settings/server'; +import { SystemLogger } from '../lib/logger/system'; Meteor.methods({ sendForgotPasswordEmail(to) { @@ -27,7 +28,7 @@ Meteor.methods({ Accounts.sendResetPasswordEmail(user._id, email); return true; } catch (error) { - console.error(error); + SystemLogger.error(error); } }, }); diff --git a/server/modules/notifications/notifications.module.ts b/server/modules/notifications/notifications.module.ts index e49939ebfe6b..dd018e18b696 100644 --- a/server/modules/notifications/notifications.module.ts +++ b/server/modules/notifications/notifications.module.ts @@ -7,6 +7,7 @@ import { UsersRaw } from '../../../app/models/server/raw/Users'; import { SettingsRaw } from '../../../app/models/server/raw/Settings'; import { IOmnichannelRoom } from '../../../definition/IRoom'; import { IUser } from '../../../definition/IUser'; +import { SystemLogger } from '../../lib/logger/system'; interface IModelsParam { Rooms: RoomsRaw; @@ -16,8 +17,6 @@ interface IModelsParam { } export class NotificationsModule { - private debug = false - public readonly streamLogged: IStreamer; public readonly streamAll: IStreamer; @@ -218,7 +217,7 @@ export class NotificationsModule { return user[key] === username; } catch (e) { - console.error(e); + SystemLogger.error(e); return false; } }); @@ -390,58 +389,34 @@ export class NotificationsModule { } notifyAll(eventName: string, ...args: any[]): void { - if (this.debug === true) { - console.log('notifyAll', [eventName, ...args]); - } return this.streamAll.emit(eventName, ...args); } notifyLogged(eventName: string, ...args: any[]): void { - if (this.debug === true) { - console.log('notifyLogged', [eventName, ...args]); - } return this.streamLogged.emit(eventName, ...args); } notifyRoom(room: string, eventName: string, ...args: any[]): void { - if (this.debug === true) { - console.log('notifyRoom', [room, eventName, ...args]); - } return this.streamRoom.emit(`${ room }/${ eventName }`, ...args); } notifyUser(userId: string, eventName: string, ...args: any[]): void { - if (this.debug === true) { - console.log('notifyUser', [userId, eventName, ...args]); - } return this.streamUser.emit(`${ userId }/${ eventName }`, ...args); } notifyAllInThisInstance(eventName: string, ...args: any[]): void { - if (this.debug === true) { - console.log('notifyAll', [eventName, ...args]); - } return this.streamAll.emitWithoutBroadcast(eventName, ...args); } notifyLoggedInThisInstance(eventName: string, ...args: any[]): void { - if (this.debug === true) { - console.log('notifyLogged', [eventName, ...args]); - } return this.streamLogged.emitWithoutBroadcast(eventName, ...args); } notifyRoomInThisInstance(room: string, eventName: string, ...args: any[]): void { - if (this.debug === true) { - console.log('notifyRoomAndBroadcast', [room, eventName, ...args]); - } return this.streamRoom.emitWithoutBroadcast(`${ room }/${ eventName }`, ...args); } notifyUserInThisInstance(userId: string, eventName: string, ...args: any[]): void { - if (this.debug === true) { - console.log('notifyUserAndBroadcast', [userId, eventName, ...args]); - } return this.streamUser.emitWithoutBroadcast(`${ userId }/${ eventName }`, ...args); } diff --git a/server/modules/streamer/streamer.module.ts b/server/modules/streamer/streamer.module.ts index dd08ac0b52a2..8498e4db9ace 100644 --- a/server/modules/streamer/streamer.module.ts +++ b/server/modules/streamer/streamer.module.ts @@ -1,5 +1,7 @@ import { EventEmitter } from 'eventemitter3'; +import { SystemLogger } from '../../lib/logger/system'; + class StreamerCentralClass extends EventEmitter { public instances: Record = {}; @@ -146,7 +148,7 @@ export abstract class Streamer extends EventEmitter implements IStreamer { } if (typeof fn === 'string' && ['all', 'none', 'logged'].indexOf(fn) === -1) { - console.error(`${ name } shortcut '${ fn }' is invalid`); + SystemLogger.error(`${ name } shortcut '${ fn }' is invalid`); } if (fn === 'all' || fn === true) { @@ -307,7 +309,7 @@ export abstract class Streamer extends EventEmitter implements IStreamer { try { this.registerMethod(method); } catch (e) { - console.error(e); + SystemLogger.error(e); } } diff --git a/server/services/nps/getAndCreateNpsSurvey.ts b/server/services/nps/getAndCreateNpsSurvey.ts index 3d0bd328c429..b79fdc0fb52f 100644 --- a/server/services/nps/getAndCreateNpsSurvey.ts +++ b/server/services/nps/getAndCreateNpsSurvey.ts @@ -6,6 +6,7 @@ import { getWorkspaceAccessToken } from '../../../app/cloud/server'; import { UiKitBannerPayload } from '../../../definition/UIKit'; import { Banner } from '../../sdk'; import { IBanner, BannerPlatform } from '../../../definition/IBanner'; +import { SystemLogger } from '../../lib/logger/system'; type NpsSurveyData = { id: string; @@ -39,7 +40,7 @@ export const getAndCreateNpsSurvey = Meteor.bindEnvironment(async function getNp }); if (result.statusCode !== 200) { - console.log('invalid response from the nps service:', result); + SystemLogger.error({ msg: 'invalid response from the nps service:', result }); return; } @@ -62,7 +63,7 @@ export const getAndCreateNpsSurvey = Meteor.bindEnvironment(async function getNp await Banner.create(banner); } catch (e) { - console.error(e); + SystemLogger.error(e); return false; } }); diff --git a/server/services/nps/sendNpsResults.ts b/server/services/nps/sendNpsResults.ts index 73ade663c082..c9e2fc9e38a1 100644 --- a/server/services/nps/sendNpsResults.ts +++ b/server/services/nps/sendNpsResults.ts @@ -4,6 +4,7 @@ import { Meteor } from 'meteor/meteor'; import { settings } from '../../../app/settings/server'; import { getWorkspaceAccessToken } from '../../../app/cloud/server'; import { INpsVote } from '../../../definition/INps'; +import { SystemLogger } from '../../lib/logger/system'; type NPSResultPayload = { total: number; @@ -26,7 +27,7 @@ export const sendNpsResults = Meteor.bindEnvironment(function sendNpsResults(nps data, }); } catch (e) { - console.error(e); + SystemLogger.error(e); return false; } }); diff --git a/server/startup/migrations/index.js b/server/startup/migrations/index.js index 3b9354a6a27c..302fdd2e1a49 100644 --- a/server/startup/migrations/index.js +++ b/server/startup/migrations/index.js @@ -229,4 +229,5 @@ import './v229'; import './v230'; import './v231'; import './v232'; +import './v233'; import './xrun'; diff --git a/server/startup/migrations/v099.js b/server/startup/migrations/v099.js index acf9dec63b82..bb26393a7d47 100644 --- a/server/startup/migrations/v099.js +++ b/server/startup/migrations/v099.js @@ -6,10 +6,10 @@ import { Match } from 'meteor/check'; import { Mongo } from 'meteor/mongo'; import { RocketChatFile } from '../../../app/file'; -import { SystemLogger } from '../../../app/logger'; import { FileUpload } from '../../../app/file-upload'; import { Migrations } from '../../../app/migrations'; import { Uploads, Settings, Users } from '../../../app/models'; +import { showErrorBox } from '../../lib/logger/showBox'; function log(...args) { console.log('[AVATAR]', ...args); @@ -139,7 +139,10 @@ Migrations.add({ } else if (Match.test(avatarsPath, String) && avatarsPath.length > 0) { avatarStoreType = 'FileSystem'; } else { - SystemLogger.error_box('Can\'t define the avatar\'s storage type.\nIf you have avatars missing and they was stored in your file system\nrun the process including the following environment variables: \n AVATARS_PATH=\'YOUR AVATAR\'S DIRECTORY\'\n MIGRATION_VERSION=99,rerun', 'WARNING'); + showErrorBox( + 'WARNING', + 'Can\'t define the avatar\'s storage type.\nIf you have avatars missing and they was stored in your file system\nrun the process including the following environment variables: \n AVATARS_PATH=\'YOUR AVATAR\'S DIRECTORY\'\n MIGRATION_VERSION=99,rerun', + ); return; } } diff --git a/server/startup/migrations/v233.ts b/server/startup/migrations/v233.ts new file mode 100644 index 000000000000..7695ef14126c --- /dev/null +++ b/server/startup/migrations/v233.ts @@ -0,0 +1,12 @@ +import { Migrations } from '../../../app/migrations/server'; +import { Settings } from '../../../app/models/server'; + +Migrations.add({ + version: 233, + up() { + Settings.remove({ _id: { $in: [ + 'Log_Package', + 'Log_File', + ] } }); + }, +}); diff --git a/server/startup/serverRunning.js b/server/startup/serverRunning.js index 67ed3ee4a62c..d030767e6432 100644 --- a/server/startup/serverRunning.js +++ b/server/startup/serverRunning.js @@ -5,11 +5,11 @@ import semver from 'semver'; import { Meteor } from 'meteor/meteor'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; -import { SystemLogger } from '../../app/logger'; import { settings } from '../../app/settings/server'; import { Info, getMongoInfo } from '../../app/utils/server'; import { Users } from '../../app/models/server'; import { sendMessagesToAdmins } from '../lib/sendMessagesToAdmins'; +import { showErrorBox, showSuccessBox, showWarningBox } from '../lib/logger/showBox'; const exitIfNotBypassed = (ignore, errorCode = 1) => { if (typeof ignore === 'string' && ['yes', 'true'].includes(ignore.toLowerCase())) { @@ -49,31 +49,31 @@ Meteor.startup(function() { if (!process.env.DISABLE_DB_WATCH && !oplogEnabled) { msg += ['', '', 'OPLOG / REPLICASET IS REQUIRED TO RUN ROCKET.CHAT, MORE INFORMATION AT:', 'https://go.rocket.chat/i/oplog-required'].join('\n'); - SystemLogger.error_box(msg, 'SERVER ERROR'); + showErrorBox('SERVER ERROR', msg); exitIfNotBypassed(process.env.BYPASS_OPLOG_VALIDATION); } if (!semver.satisfies(process.versions.node, desiredNodeVersionMajor)) { msg += ['', '', 'YOUR CURRENT NODEJS VERSION IS NOT SUPPORTED,', `PLEASE UPGRADE / DOWNGRADE TO VERSION ${ desiredNodeVersionMajor }.X.X`].join('\n'); - SystemLogger.error_box(msg, 'SERVER ERROR'); + showErrorBox('SERVER ERROR', msg); exitIfNotBypassed(process.env.BYPASS_NODEJS_VALIDATION); } if (!semver.satisfies(semver.coerce(mongoVersion), '>=3.4.0')) { msg += ['', '', 'YOUR CURRENT MONGODB VERSION IS NOT SUPPORTED,', 'PLEASE UPGRADE TO VERSION 3.4 OR LATER'].join('\n'); - SystemLogger.error_box(msg, 'SERVER ERROR'); + showErrorBox('SERVER ERROR', msg); exitIfNotBypassed(process.env.BYPASS_MONGO_VALIDATION); } - SystemLogger.startup_box(msg, 'SERVER RUNNING'); + showSuccessBox('SERVER RUNNING', msg); // Deprecation if (!semver.satisfies(semver.coerce(mongoVersion), '>=3.6.0')) { msg = [`YOUR CURRENT MONGODB VERSION (${ mongoVersion }) IS DEPRECATED.`, 'IT WILL NOT BE SUPPORTED ON ROCKET.CHAT VERSION 4.0.0 AND GREATER,', 'PLEASE UPGRADE MONGODB TO VERSION 3.6 OR GREATER'].join('\n'); - SystemLogger.deprecation_box(msg, 'DEPRECATION'); + showWarningBox('DEPRECATION', msg); const id = `mongodbDeprecation_${ mongoVersion.replace(/[^0-9]/g, '_') }`; const title = 'MongoDB_Deprecated'; diff --git a/server/stream/streamBroadcast.js b/server/stream/streamBroadcast.js index bf60f7c93340..a1329f19da77 100644 --- a/server/stream/streamBroadcast.js +++ b/server/stream/streamBroadcast.js @@ -4,7 +4,7 @@ import { InstanceStatus } from 'meteor/konecty:multiple-instances-status'; import { check } from 'meteor/check'; import { DDP } from 'meteor/ddp'; -import { Logger, LoggerManager } from '../../app/logger'; +import { Logger } from '../lib/logger/Logger'; import { hasPermission } from '../../app/authorization'; import { settings } from '../../app/settings'; import { isDocker, getURL } from '../../app/utils'; @@ -19,24 +19,22 @@ process.env.INSTANCE_IP = String(process.env.INSTANCE_IP).trim(); const connections = {}; this.connections = connections; -const logger = new Logger('StreamBroadcast', { - sections: { - connection: 'Connection', - auth: 'Auth', - stream: 'Stream', - }, -}); +const logger = new Logger('StreamBroadcast'); + +export const connLogger = logger.section('Connection'); +export const authLogger = logger.section('Auth'); +export const streamLogger = logger.section('Stream'); function _authorizeConnection(instance) { - logger.auth.info(`Authorizing with ${ instance }`); + authLogger.info(`Authorizing with ${ instance }`); return connections[instance].call('broadcastAuth', InstanceStatus.id(), connections[instance].instanceId, function(err, ok) { if (err != null) { - return logger.auth.error(`broadcastAuth error ${ instance } ${ InstanceStatus.id() } ${ connections[instance].instanceId }`, err); + return authLogger.error({ msg: `broadcastAuth error ${ instance } ${ InstanceStatus.id() } ${ connections[instance].instanceId }`, err }); } connections[instance].broadcastAuth = ok; - return logger.auth.info(`broadcastAuth with ${ instance }`, ok); + return authLogger.info({ msg: `broadcastAuth with ${ instance }`, ok }); }); } @@ -70,7 +68,7 @@ function startMatrixBroadcast() { let instance = `${ record.extraInformation.host }:${ record.extraInformation.port }${ subPath }`; if (record.extraInformation.port === process.env.PORT && record.extraInformation.host === process.env.INSTANCE_IP) { - logger.auth.info('prevent self connect', instance); + authLogger.info({ msg: 'prevent self connect', instance }); return; } @@ -87,10 +85,10 @@ function startMatrixBroadcast() { } } - logger.connection.info('connecting in', instance); + connLogger.info({ msg: 'connecting in', instance }); connections[instance] = DDP.connect(instance, { - _dontPrintErrors: LoggerManager.logLevel < 2, + _dontPrintErrors: settings.get('Log_Level') !== '2', }); // remove not relevant info from instance record @@ -124,7 +122,7 @@ function startMatrixBroadcast() { }; if (connections[instance] && !InstanceStatus.getCollection().findOne(query)) { - logger.connection.info('disconnecting from', instance); + connLogger.info({ msg: 'disconnecting from', instance }); connections[instance].disconnect(); return delete connections[instance]; } @@ -150,7 +148,7 @@ function startMatrixBroadcast() { function startStreamCastBroadcast(value) { const instance = 'StreamCast'; - logger.connection.info('connecting in', instance, value); + connLogger.info({ msg: 'connecting in', instance, value }); if (!isPresenceMonitorEnabled()) { UserPresence.setDefaultStatus = (id, status) => { @@ -159,7 +157,7 @@ function startStreamCastBroadcast(value) { } const connection = DDP.connect(value, { - _dontPrintErrors: LoggerManager.logLevel < 2, + _dontPrintErrors: settings.get('Log_Level') !== '2', }); connections[instance] = connection; @@ -231,26 +229,39 @@ export function startStreamBroadcast() { if (connection.status().connected === true) { connection.call('stream', streamName, eventName, args, function(error, response) { if (error) { - logger.error('Stream broadcast error', error); + logger.error({ msg: 'Stream broadcast error', err: error }); } switch (response) { case 'self-not-authorized': - logger.stream.error(`Stream broadcast from '${ fromInstance }' to '${ connection._stream.endpoint }' with name ${ streamName } to self is not authorized`.red); - logger.stream.debug(' -> connection authorized'.red, connection.broadcastAuth); - logger.stream.debug(' -> connection status'.red, connection.status()); - return logger.stream.debug(' -> arguments'.red, eventName, args); + streamLogger.error(`Stream broadcast from '${ fromInstance }' to '${ connection._stream.endpoint }' with name ${ streamName } to self is not authorized`); + streamLogger.debug({ + msg: 'self-not-authorized', + broadcastAuth: connection.broadcastAuth, + status: connection.status(), + eventName, + args, + }); + return; case 'not-authorized': - logger.stream.error(`Stream broadcast from '${ fromInstance }' to '${ connection._stream.endpoint }' with name ${ streamName } not authorized`.red); - logger.stream.debug(' -> connection authorized'.red, connection.broadcastAuth); - logger.stream.debug(' -> connection status'.red, connection.status()); - logger.stream.debug(' -> arguments'.red, eventName, args); + streamLogger.error(`Stream broadcast from '${ fromInstance }' to '${ connection._stream.endpoint }' with name ${ streamName } not authorized`); + streamLogger.debug({ + msg: 'not-authorized', + broadcastAuth: connection.broadcastAuth, + status: connection.status(), + eventName, + args, + }); return authorizeConnection(instance); case 'stream-not-exists': - logger.stream.error(`Stream broadcast from '${ fromInstance }' to '${ connection._stream.endpoint }' with name ${ streamName } does not exist`.red); - logger.stream.debug(' -> connection authorized'.red, connection.broadcastAuth); - logger.stream.debug(' -> connection status'.red, connection.status()); - return logger.stream.debug(' -> arguments'.red, eventName, args); + streamLogger.error(`Stream broadcast from '${ fromInstance }' to '${ connection._stream.endpoint }' with name ${ streamName } does not exist`); + streamLogger.debug({ + msg: 'stream-not-exists', + broadcastAuth: connection.broadcastAuth, + status: connection.status(), + eventName, + args, + }); } }); } From 5a8d666f30a3170d34f3966a09439278b679ff20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Sep 2021 15:29:45 -0300 Subject: [PATCH 04/15] Bump xml-crypto from 2.1.2 to 2.1.3 (#23141) Bumps [xml-crypto](https://github.com/yaronn/xml-crypto) from 2.1.2 to 2.1.3. - [Release notes](https://github.com/yaronn/xml-crypto/releases) - [Commits](https://github.com/yaronn/xml-crypto/compare/v2.1.2...v2.1.3) --- updated-dependencies: - dependency-name: xml-crypto dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 13 +++++++++---- package.json | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b28bab4daa91..c920a6da8ec3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10807,6 +10807,11 @@ "@xtuc/long": "4.2.2" } }, + "@xmldom/xmldom": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.4.tgz", + "integrity": "sha512-wdxC79cvO7PjSM34jATd/RYZuYWQ8y/R7MidZl1NYYlbpFn1+spfjkiR3ZsJfcaTs2IyslBN7VwBBJwrYKM+zw==" + }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -37876,11 +37881,11 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" }, "xml-crypto": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.2.tgz", - "integrity": "sha512-DBhZXtBjENtLwJmeJhLUBwUm9YWNjCRvAx6ESP4VJyM9PDuKqZu2Fp5Y5HKqcdJT7vV7eI25Z4UBMezji6QloQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.3.tgz", + "integrity": "sha512-MpXZwnn9JK0mNPZ5mnFIbNnQa+8lMGK4NtnX2FlJMfMWR60sJdFO9X72yO6ji068pxixzk53O7x0/iSKh6IhyQ==", "requires": { - "xmldom": "^0.6.0", + "@xmldom/xmldom": "^0.7.0", "xpath": "0.0.32" }, "dependencies": { diff --git a/package.json b/package.json index 6f310875d1d4..126e137b9b28 100644 --- a/package.json +++ b/package.json @@ -288,7 +288,7 @@ "use-subscription": "^1.5.1", "uuid": "^3.4.0", "webdav": "^2.10.2", - "xml-crypto": "^2.1.2", + "xml-crypto": "^2.1.3", "xml-encryption": "0.11.2", "xml2js": "0.4.23", "xmldom": "^0.6.0", From fad5585769e89da6eb09b242d89a94b6d301df54 Mon Sep 17 00:00:00 2001 From: Matheus Barbosa Silva <36537004+matheusbsilva137@users.noreply.github.com> Date: Wed, 8 Sep 2021 21:00:42 -0300 Subject: [PATCH 05/15] [FIX] Inaccurate use of 'Mobile notifications' instead of 'Push notifications' in i18n strings (#22978) * Replace Mobile Notifications by Push-Notifications * Update key name * Update more key names * Fix tests * Update user account preferences keys Co-authored-by: Leonardo Ostjen Couto --- app/lib/server/functions/notifications/mobile.js | 4 ++-- app/lib/server/startup/settings.js | 2 +- app/utils/lib/getUserNotificationPreference.js | 2 +- .../preferences/PreferencesNotificationsSection.js | 6 +++--- packages/rocketchat-i18n/i18n/af.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ar.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/az.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/be-BY.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/bg.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/bs.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ca.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/cs.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/cy.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/da.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/de-AT.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/de-IN.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/de.i18n.json | 8 ++++---- packages/rocketchat-i18n/i18n/el.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/en.i18n.json | 8 ++++---- packages/rocketchat-i18n/i18n/eo.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/es.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/fa.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/fi.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/fr.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/hi-IN.i18n.json | 4 ++-- packages/rocketchat-i18n/i18n/hr.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/hu.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/id.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/it.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ja.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ka-GE.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/km.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ko.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ku.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/lo.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/lt.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/lv.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/mn.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ms-MY.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/nl.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/no.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/pl.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/pt-BR.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/pt.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ro.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ru.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/sk-SK.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/sl-SI.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/sq.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/sr.i18n.json | 4 ++-- packages/rocketchat-i18n/i18n/sv.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/ta-IN.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/th-TH.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/tr.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/uk.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/vi-VN.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/zh-HK.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/zh-TW.i18n.json | 6 +++--- packages/rocketchat-i18n/i18n/zh.i18n.json | 6 +++--- server/startup/migrations/v105.js | 2 +- server/startup/migrations/v161.js | 4 ++-- tests/cypress/pageobjects/administration.page.js | 4 ++-- tests/end-to-end/api/00-miscellaneous.js | 2 +- 63 files changed, 178 insertions(+), 178 deletions(-) diff --git a/app/lib/server/functions/notifications/mobile.js b/app/lib/server/functions/notifications/mobile.js index 4dca10c46561..7211f9e0dfcf 100644 --- a/app/lib/server/functions/notifications/mobile.js +++ b/app/lib/server/functions/notifications/mobile.js @@ -96,10 +96,10 @@ export function shouldNotifyMobile({ } if (!mobilePushNotifications) { - if (settings.get('Accounts_Default_User_Preferences_mobileNotifications') === 'all' && (!isThread || hasReplyToThread)) { + if (settings.get('Accounts_Default_User_Preferences_pushNotifications') === 'all' && (!isThread || hasReplyToThread)) { return true; } - if (settings.get('Accounts_Default_User_Preferences_mobileNotifications') === 'nothing') { + if (settings.get('Accounts_Default_User_Preferences_pushNotifications') === 'nothing') { return false; } } diff --git a/app/lib/server/startup/settings.js b/app/lib/server/startup/settings.js index ed49305189c6..4a851e9adcac 100644 --- a/app/lib/server/startup/settings.js +++ b/app/lib/server/startup/settings.js @@ -295,7 +295,7 @@ settings.addGroup('Accounts', function() { ], public: true, }); - this.add('Accounts_Default_User_Preferences_mobileNotifications', 'all', { + this.add('Accounts_Default_User_Preferences_pushNotifications', 'all', { type: 'select', values: [ { diff --git a/app/utils/lib/getUserNotificationPreference.js b/app/utils/lib/getUserNotificationPreference.js index ce80cd5befbb..bab787117d6f 100644 --- a/app/utils/lib/getUserNotificationPreference.js +++ b/app/utils/lib/getUserNotificationPreference.js @@ -10,7 +10,7 @@ export const getUserNotificationPreference = (user, pref) => { switch (pref) { case 'audio': preferenceKey = 'audioNotifications'; break; case 'desktop': preferenceKey = 'desktopNotifications'; break; - case 'mobile': preferenceKey = 'mobileNotifications'; break; + case 'mobile': preferenceKey = 'pushNotifications'; break; case 'email': preferenceKey = 'emailNotificationMode'; break; } diff --git a/client/views/account/preferences/PreferencesNotificationsSection.js b/client/views/account/preferences/PreferencesNotificationsSection.js index 5d1aabb326fd..b2c9dbf40ac8 100644 --- a/client/views/account/preferences/PreferencesNotificationsSection.js +++ b/client/views/account/preferences/PreferencesNotificationsSection.js @@ -35,7 +35,7 @@ const PreferencesNotificationsSection = ({ onChange, commitRef, ...props }) => { 'desktopNotificationRequireInteraction', ); const userDesktopNotifications = useUserPreference('desktopNotifications'); - const userMobileNotifications = useUserPreference('mobileNotifications'); + const userMobileNotifications = useUserPreference('pushNotifications'); const userEmailNotificationMode = useUserPreference('emailNotificationMode'); const userDesktopAudioNotifications = useUserPreference('audioNotifications'); @@ -46,7 +46,7 @@ const PreferencesNotificationsSection = ({ onChange, commitRef, ...props }) => { 'Accounts_Default_User_Preferences_audioNotifications', ); const defaultMobileNotifications = useSetting( - 'Accounts_Default_User_Preferences_mobileNotifications', + 'Accounts_Default_User_Preferences_pushNotifications', ); const canChangeEmailNotification = useSetting('Accounts_AllowEmailNotifications'); @@ -194,7 +194,7 @@ const PreferencesNotificationsSection = ({ onChange, commitRef, ...props }) => { - {t('Notification_Mobile_Default_For')} + {t('Notification_Push_Default_For')}