about summary refs log tree commit diff
path: root/src/logger
diff options
context:
space:
mode:
Diffstat (limited to 'src/logger')
-rw-r--r--src/logger/__tests__/logger.test.ts2
-rw-r--r--src/logger/index.ts30
2 files changed, 30 insertions, 2 deletions
diff --git a/src/logger/__tests__/logger.test.ts b/src/logger/__tests__/logger.test.ts
index f8b588778..12d60abaa 100644
--- a/src/logger/__tests__/logger.test.ts
+++ b/src/logger/__tests__/logger.test.ts
@@ -179,6 +179,7 @@ describe('general functionality', () => {
       level: 'debug', // Sentry bug, log becomes debug
       timestamp: sentryTimestamp,
     })
+    jest.runAllTimers()
     expect(Sentry.captureMessage).toHaveBeenCalledWith(message, {
       level: 'log',
       tags: undefined,
@@ -193,6 +194,7 @@ describe('general functionality', () => {
       level: 'warning',
       timestamp: sentryTimestamp,
     })
+    jest.runAllTimers()
     expect(Sentry.captureMessage).toHaveBeenCalledWith(message, {
       level: 'warning',
       tags: undefined,
diff --git a/src/logger/index.ts b/src/logger/index.ts
index f03850767..733d0e4b0 100644
--- a/src/logger/index.ts
+++ b/src/logger/index.ts
@@ -170,8 +170,8 @@ export const sentryTransport: Transport = (
         [LogLevel.Warn]: 'warning',
         [LogLevel.Error]: 'error',
       }[level] || 'log') as Sentry.Breadcrumb['level']
-
-      Sentry.captureMessage(message, {
+      // Defer non-critical messages so they're sent in a batch
+      queueMessageForSentry(message, {
         level: messageLevel,
         tags,
         extra: meta,
@@ -188,6 +188,32 @@ export const sentryTransport: Transport = (
   }
 }
 
+const queuedMessages: [string, Parameters<typeof Sentry.captureMessage>[1]][] =
+  []
+let sentrySendTimeout: ReturnType<typeof setTimeout> | null = null
+function queueMessageForSentry(
+  message: string,
+  captureContext: Parameters<typeof Sentry.captureMessage>[1],
+) {
+  queuedMessages.push([message, captureContext])
+  if (!sentrySendTimeout) {
+    // Throttle sending messages with a leading delay
+    // so that we can get Sentry out of the critical path.
+    sentrySendTimeout = setTimeout(() => {
+      sentrySendTimeout = null
+      sendQueuedMessages()
+    }, 7000)
+  }
+}
+function sendQueuedMessages() {
+  while (queuedMessages.length > 0) {
+    const record = queuedMessages.shift()
+    if (record) {
+      Sentry.captureMessage(record[0], record[1])
+    }
+  }
+}
+
 /**
  * Main class. Defaults are provided in the constructor so that subclasses are
  * technically possible, if we need to go that route in the future.