Throttle non-critical Sentry messages (#2110)

* Throttle non-critical Sentry messages

* Run all timers in tests
zio/stable
dan 2023-12-06 16:32:47 +00:00 committed by GitHub
parent df55c5fdeb
commit 7229cda5a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 2 deletions

View File

@ -37,6 +37,7 @@ const dist = `${Platform.OS}.${release}${
}`
init({
autoSessionTracking: false,
dsn: 'https://05bc3789bf994b81bd7ce20c86ccd3ae@o4505071687041024.ingest.sentry.io/4505071690514432',
debug: false, // If `true`, Sentry will try to print out useful debugging information if something goes wrong with sending the event. Set it to `false` in production
enableInExpoDevelopment: true,

View File

@ -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,

View File

@ -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.