-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
feat: Add express & fastify tunnel examples #8144
Changes from all commits
daca091
eee499b
0c76878
eb79f90
116e7d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -103,7 +103,99 @@ Sentry.init({ | |||||
}); | ||||||
``` | ||||||
|
||||||
Once configured, all events will be sent to the `/tunnel` endpoint. This solution, however, requires an additional configuration on the server, as the events now need to be parsed and redirected to Sentry. Here's an example for your server component: | ||||||
Once configured, all events will be sent to the `/tunnel` endpoint. This will require an additional configuration on the server because the events will need to be parsed and redirected to Sentry. | ||||||
|
||||||
### Using a Tunneling Server | ||||||
|
||||||
Here's an example of how to set up an endpoint on your server that will tunnel events to Sentry: | ||||||
|
||||||
```js {tabTitle:Express} | ||||||
// Change this to suit your needs | ||||||
const SENTRY_HOST = "oXXXXXX.ingest.sentry.io"; | ||||||
const SENTRY_KNOWN_PROJECTS = ["123456"]; | ||||||
|
||||||
app.post("/bugs", (req, res) => { | ||||||
try { | ||||||
const envelope = req.body; | ||||||
|
||||||
const piece = envelope.toString().split("\n")[0]; | ||||||
const header = JSON.parse(piece); | ||||||
|
||||||
const dsn = new URL(header.dsn); | ||||||
if (dsn.hostname !== SENTRY_HOST) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m: I assume we do this so that the endpoint can't be abused. We should add a comment to describe this because strictly speaking Ditto for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, this is based on the existing tunnel examples, where they have set this up in a similar way too 🤔 not sure if it helps to explain this more, or just bloats this up? IMHO we can also just leave this away if we want to keep this as simple as possible, not sure how important this check is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No hard feelings either way. Let me downgrade this to logaf l. I think it makes sense for users to be aware of abuse potential. We can just leave it as is (without explanation) and add it if we see a lot of people asking about it, which is not gonna happen anyhow. Removing it would probably be handing people a footgun which I don't particularly like. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay nevermind let's keep this for sure! |
||||||
throw new Error(`Invalid Sentry host: ${dsn.hostname}`); | ||||||
} | ||||||
|
||||||
const projectId = dsn.pathname.substring(1); | ||||||
if (!SENTRY_KNOWN_PROJECTS.includes(projectId)) { | ||||||
throw new Error(`Invalid Project ID: ${projectId}`); | ||||||
} | ||||||
|
||||||
const url = `https://${SENTRY_HOST}/api/${projectId}/envelope/`; | ||||||
fetch(url, { | ||||||
method: "POST", | ||||||
body: envelope, | ||||||
headers: { | ||||||
"Content-Type": "application/x-sentry-envelope", | ||||||
}, | ||||||
}).then( | ||||||
() => { | ||||||
res.sendStatus(204); | ||||||
}, | ||||||
(error) => { | ||||||
res.sendStatus(400).send({ message: error.message }); | ||||||
} | ||||||
); | ||||||
} catch (error) { | ||||||
res.sendStatus(400).send({ message: error.message }); | ||||||
} | ||||||
}); | ||||||
``` | ||||||
|
||||||
```js {tabTitle:Fastify} | ||||||
// Change this to suit your needs | ||||||
const SENTRY_HOST = "oXXXXXX.ingest.sentry.io"; | ||||||
const SENTRY_KNOWN_PROJECTS = ["123456"]; | ||||||
|
||||||
// Handle replay packets where no content-type header is available | ||||||
fastify.addContentTypeParser( | ||||||
"*", | ||||||
{ parseAs: "buffer" }, | ||||||
function (req, body, done) { | ||||||
done(null, body); | ||||||
} | ||||||
); | ||||||
fastify.post("/bugs", async (request, reply) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
try { | ||||||
const envelope = request.body; | ||||||
|
||||||
const piece = envelope.toString().split("\n")[0]; | ||||||
const header = JSON.parse(piece); | ||||||
|
||||||
const dsn = new URL(header.dsn); | ||||||
if (dsn.hostname !== SENTRY_HOST) { | ||||||
throw new Error(`Invalid Sentry host: ${dsn.hostname}`); | ||||||
} | ||||||
|
||||||
const projectId = dsn.pathname.substring(1); | ||||||
if (!SENTRY_KNOWN_PROJECTS.includes(projectId)) { | ||||||
throw new Error(`Invalid Project ID: ${projectId}`); | ||||||
} | ||||||
|
||||||
const url = `https://${SENTRY_HOST}/api/${projectId}/envelope/`; | ||||||
await fetch(url, { | ||||||
method: "POST", | ||||||
body: envelope, | ||||||
headers: { | ||||||
"Content-Type": "application/x-sentry-envelope", | ||||||
}, | ||||||
}); | ||||||
} catch (error) { | ||||||
return reply.code(400).send({ message: error.message }); | ||||||
} | ||||||
return reply.code(204).send(); | ||||||
}); | ||||||
``` | ||||||
|
||||||
```csharp | ||||||
// Requires .NET Core 3.1 and C# 9 or higher | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.