MultiTransport with version 7.x #7420
-
Hello, I have found this MultiTransport class written in Python that sends all events to two instances of sentry at once. We are currently moving from one instance to another and wanted to run them parallel to each other in case the new sentry has issues.
I can't seem to convert this into something that works in version 7.x as it's impossible to import BrowserOptions or access the makeRequest function from outside the makeXXXXTransport() functions. I created this in an attempt to make multi transport work, but it's not even sending errors to one of the dsn
I am aware I could theorhetically make a separate BrowserClient for each dsn and then duplicate every call to Sentry, but that would require me to modify a rather massive amount of files and would leave the possibility for someone to accidentally omit one of the sentry instances when using sentry in the future. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
I suppose this is one of those moments when you find a better solution after asking a question:
kind of works, the sentry with DSN1 gets "TESTING TESTING" just fine, however, |
Beta Was this translation helpful? Give feedback.
-
The issue with the first approach is that you have to convert the DSN to be a URL to send to. You can do this via the const dsn = makeDsn("STRING DSN HERE");
const url = getEnvelopeEndpointWithUrlEncodedAuth(dsn); Below is an example that should work - but I haven't tested it. Pay special attention to the fact that it respects rate limits, which is important. /**
* Creates a Transport that uses the Fetch API to send events to multiple Sentry DSNs.
*/
export function makeMultiTransport(options: BrowserTransportOptions): Transport {
function makeRequest(request: TransportRequest): PromiseLike<TransportMakeRequestResponse> {
const requestOptions: RequestInit = {
body: request.body,
method: 'POST',
referrerPolicy: 'origin',
headers: options.headers,
keepalive: request.body.length <= 65536,
...options.fetchOptions,
};
try {
return Promise.all(
['FIRST_DSN_HERE', 'SECOND_DSN_HERE'].map(dsnString => {
const dsn = makeDsn(dsnString);
const url = getEnvelopeEndpointWithUrlEncodedAuth(dsn);
return fetch(url, requestOptions).then(response => ({
statusCode: response.status,
headers: {
'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),
'retry-after': response.headers.get('Retry-After'),
},
}));
}),
).then((transportResponses: TransportMakeRequestResponse[]) => {
// Return first response that has rate limits
for (const response of transportResponses) {
if (response && response.headers && response.headers['x-sentry-rate-limits']) {
return response;
}
}
// Otherwise just return first response
return transportResponses[0];
});
} catch (e) {
return rejectedSyncPromise(e);
}
}
return createTransport(options, makeRequest);
} |
Beta Was this translation helpful? Give feedback.
The issue with the first approach is that you have to convert the DSN to be a URL to send to. You can do this via the
makeDsn
andgetEnvelopeEndpointWithUrlEncodedAuth
that is exported from the base packages.Below is an example that should work - but I haven't tested it. Pay special attention to the fact that it respects rate limits, which is important.