#I am using Tunnel in Sentry in Next.js. Replay is not working post that?

1 messages · Page 1 of 1 (latest)

keen shoal
#

I am using tunneling feature in Sentry to support ad blockers. Post that i observed that replay feature is not working. Also the real IP is not logged.

wispy kite
#

real ip logging will of course not work because you are proxying requests. You could use middleware to add a forwarded for header.

#

Can you share a bit more information why replay is not working?

keen shoal
#

Can we get on a call for this?

wispy kite
#

Hi, sorry no that is not possible for time reasons. Feel free to ask away here though or contact Sentry support.

keen shoal
#

I have sufficeient replay quota left. Post implementing the tunneling feature I am not able to see any replay for any error.

const SENTRY_HOST = "xxxx";
const SENTRY_PROJECT_IDS = ["xxx"];

const handler = async (request, response) => {
  try {
    const envelope = request.body;
    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 !== SENTRY_HOST) {
      throw new Error(`Invalid sentry hostname: ${dsn.hostname}`);
    }

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

    const upstream_sentry_url = `https://${SENTRY_HOST}/api/${project_id}/envelope/?sentry_key=xxx`;
    await fetch(upstream_sentry_url, { method: "POST", body: envelope });

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

export default handler;
#

my sentry client config

// This file configures the initialization of Sentry on the client.
// The config you add here will be used whenever a users loads a page in their browser.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "url
",
  environment: process.env.NEXT_PUBLIC_ENVIRONMENT,
  enabled: process.env.NEXT_PUBLIC_ENABLE_SENTRY === 'true',

  // Adjust this value in production, or use tracesSampler for greater control
  tracesSampleRate: 0.5,
  integrations: [Sentry.browserTracingIntegration(), Sentry.browserProfilingIntegration(), new Sentry.BrowserProfilingIntegration(), Sentry.replayIntegration({
    // Additional Replay configuration goes in here, for example:
    maskAllText: true,
    blockAllMedia: true,
  })],
  tracePropagationTargets: [/^https:\/\/delta\.convai\.com/, /^https:\/\/www\.convai\.com/],

  // Setting this option to true will print useful information to the console while you're setting up Sentry.
  debug: true,

  replaysOnErrorSampleRate: 1,

  // This sets the sample rate to be 10%. You may want this to be 100% while
  // in development and sample at a lower rate in production
  replaysSessionSampleRate: 1,
});
wispy kite
#

What does your stats page say for replay events in sentry? Does your proxy log anything?

keen shoal
#

not sure what should i log. can you please help?

wispy kite
#

that looks good

#

what does your network tab say

#

are replay events sent?

keen shoal
#

getting 200 for all requests

wispy kite
#

Can you add logging to the proxy. What is it sending? Does it look the same like in the network tab?

keen nimbus
#

I had the same issue with the replays not showing up because in my case, when sending the replay, ExpressJS wouldnt properly handle data when Replay came. When the type of the request was event/trace it worked properly, but when the type of the request was replay, ExpressJS didnt properly handle it as it was Buffer

keen nimbus
#

this is my full code, hope it can help you.

const rawBufferParser = bodyParser.raw({ inflate: true, limit: '10mb', type: () => true })

app.post('/api/tunnel', rawBufferParser, async (req, res) => {
  try {
    if (!Buffer.isBuffer(req.body)) {
      await nonBinarySentryTunnel(req, res);
    }
    else {
      await binarySentryTunnel(req, res);
    }
  } catch (e) {
    console.error("error tunneling to sentry", e);
    res.status(500).json({ error: "error tunneling to sentry" });
  }
});

const nonBinarySentryTunnel = async (req, res) => {
  try {
    const envelope = req.body;
    const [rawHeader, ...restPieces] = envelope.split('\n');

    const header = JSON.parse(rawHeader);
    const dsn = new URL(header["dsn"]);
    const project_id = dsn.pathname?.replace("/", "");

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

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

    let forwarded_for = typeof req.headers['x-forwarded-for'] === 'string'
      ? req.headers['x-forwarded-for']
      : req.socket.remoteAddress;

    const upstream_sentry_url = `https://${SENTRY_HOST}/api/${project_id}/envelope/`;
    const response = await fetch(upstream_sentry_url, { headers: { "x-forwarded-for": forwarded_for }, method: "POST", body: req.body });
    if (response.status != 200) {
      console.error(response);
      res.status(503);
    }
    res.status(200).json({});
  } catch (e) {
    console.error("error tunneling to sentry", e);
    res.status(500).json({ error: "error tunneling to sentry" });
  }
}