Skip to content

Tunneling: Improve JavaScript SDK API #14248

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
AbhiPrasad opened this issue Nov 12, 2024 · 1 comment
Open

Tunneling: Improve JavaScript SDK API #14248

AbhiPrasad opened this issue Nov 12, 2024 · 1 comment

Comments

@AbhiPrasad
Copy link
Member

Description

ref https://github.com/getsentry/projects/issues/385 and https://www.notion.so/sentry/Project-Improve-Tunneling-1368b10e4b5d80b38557c66fbcf6d8a1

Right now there is a singular option for tunnel in Sentry.init that you pass in to enable tunneling. This makes setup very simple, which is a positive, but it has drawbacks.

  1. Complicates SDK internals because we end up passing tunnel config everywhere
  2. No finely grained control over what gets tunneled (a user may decide to tunnel only errors so that there is less load on their proxy infrastructure they set up). This came up in [Tunnel Options] Allow Configuration Based on Event Category #13520.
  3. We always send to tunnel endpoints, even when end-users don't have a adblocker set up
  4. There is a very slight bundle size increase (but not that important): chore: Check bundle size of removing tunnel #14223

To address this, we should improve the tunneling API within the Sentry SDKs

Investigate

  1. Do ad blockers block based on envelope payload? If they do, we might need to investigate alternate formats.

Explore

  1. Explore alternate ways to configure tunneling in the SDK. Use tunnel transport rather than top level tunnel option #14152 raises a custom transport, but perhaps an integration also works well.

Implement

  1. Can we detect in our SDKs if an ad blocker blocks our requests? If yes, we could try to send the data first directly to Sentry, and if it doesn't work, use the tunnel.

With that approach, we take most of our load from our user's infrastructure. Furthermore, we could identify how much data comes through the tunnel and how much directly via Sentry when adding metadata to the tunneled envelopes. We could also share that data with our users.

@matthijs166
Copy link

matthijs166 commented Dec 29, 2024

I'm loving the way the next.js SDK is setting this up, now I have to implement a custom route for tunnelling.

The following setup works for the arc browser. (think it uses uBlock under the hood)

/routes/monitoring/+server.ts

import { PUBLIC_SENTRY_DSN } from '$env/static/public';
import { json } from '@sveltejs/kit';

export async function POST({ request }) {
    try {
        const serverDSN = parseDSN(PUBLIC_SENTRY_DSN);
        const envelopeBytes = await request.arrayBuffer();
        const envelope = new TextDecoder().decode(envelopeBytes);
        const piece = envelope.split("\n")[0];
        const header = JSON.parse(piece);
        const dsn = new URL(header["dsn"]);
        const project_id = dsn.pathname?.replace("/", "");

        if (dsn.hostname !== serverDSN.host) {
            throw new Error(`Invalid sentry hostname: ${dsn.hostname}`);
        }

        if (!project_id || !serverDSN.projectIDs.includes(project_id)) {
            throw new Error(`Invalid sentry project id: ${project_id}`);
        }

        const upstream_sentry_url = `https://${serverDSN.host}/api/${project_id}/envelope/`;
        await fetch(upstream_sentry_url, {
            method: "POST",
            body: envelopeBytes,
        });

        return json({}, { status: 200 });
    } catch (e) {
        console.error("error tunneling to sentry", e);
        return json({ error: "error tunneling to sentry" }, { status: 500 });
    }
}

function parseDSN(dsn: string) {
    const url = new URL(dsn);
    const id = url.pathname?.replace("/", "");
    return {
        host: url.hostname,
        projectIDs: [id]
    };
}

hooks.client.ts:

Sentry.init({
  enabled: PUBLIC_SENTRY_ENABLED === 'true',
  dsn: PUBLIC_SENTRY_DSN,
  environment: PUBLIC_SENTRY_ENVIRONMENT,
  tunnel: '/monitoring',
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

3 participants