-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(browser): Add support for streamed spans in httpContextIntegration
#20464
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
base: develop
Are you sure you want to change the base?
Changes from all commits
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 |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import * as Sentry from '@sentry/browser'; | ||
|
|
||
| window.Sentry = Sentry; | ||
|
|
||
| Sentry.init({ | ||
| dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
| integrations: [Sentry.spanStreamingIntegration(), Sentry.browserTracingIntegration()], | ||
| tracesSampleRate: 1.0, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import { expect } from '@playwright/test'; | ||
| import { sentryTest } from '../../../utils/fixtures'; | ||
| import { shouldSkipTracingTest } from '../../../utils/helpers'; | ||
| import { getSpanOp, waitForStreamedSpans } from '../../../utils/spanUtils'; | ||
|
|
||
| sentryTest('httpContextIntegration captures url, user-agent, and referer', async ({ getLocalTestUrl, page }) => { | ||
| sentryTest.skip(shouldSkipTracingTest()); | ||
| const url = await getLocalTestUrl({ testDir: __dirname }); | ||
|
|
||
| const spansPromise = waitForStreamedSpans(page, spans => spans.some(s => getSpanOp(s) === 'pageload')); | ||
|
|
||
| await page.goto(url, { referer: 'https://sentry.io/' }); | ||
|
|
||
| const spans = await spansPromise; | ||
|
|
||
| const pageloadSpan = spans.find(s => getSpanOp(s) === 'pageload'); | ||
|
|
||
| expect(pageloadSpan!.attributes?.['url.full']).toEqual({ type: 'string', value: expect.any(String) }); | ||
| expect(pageloadSpan!.attributes?.['http.request.header.user_agent']).toEqual({ | ||
| type: 'string', | ||
| value: expect.any(String), | ||
| }); | ||
| expect(pageloadSpan!.attributes?.['http.request.header.referer']).toEqual({ | ||
| type: 'string', | ||
| value: 'https://sentry.io/', | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,5 +26,20 @@ export const httpContextIntegration = defineIntegration(() => { | |
| headers, | ||
| }; | ||
| }, | ||
| processSegmentSpan(span) { | ||
| // if none of the information we want exists, don't bother | ||
| if (!WINDOW.navigator && !WINDOW.location && !WINDOW.document) { | ||
| return; | ||
| } | ||
|
|
||
| const reqData = getHttpRequestData(); | ||
|
|
||
| span.attributes = { | ||
| 'url.full': reqData.url, | ||
|
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. Bug: The code unconditionally sets Suggested FixConditionally set the Prompt for AI Agent
Member
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. ^^ this also seems legitimate, we likely need to make sure that passing in |
||
| 'http.request.header.user_agent': reqData.headers['User-Agent'], | ||
| 'http.request.header.referer': reqData.headers['Referer'], | ||
|
nicohrubec marked this conversation as resolved.
|
||
| ...span.attributes, | ||
| }; | ||
|
nicohrubec marked this conversation as resolved.
|
||
| }, | ||
| }; | ||
| }); | ||
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.
l: instead of spreading this here, can we just set the attributes we want to set directly? IMHO we can just have a utility we keep using like
setIfNotExists(span.attributes, 'url.full', reqData.url), or similar? Not 100% sure but I'd suspect this is faster at scale than creating a new object all the time when processing spans like this?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.
We have a utility
@sentry/corethat does exactly what we would want I think (ref). We could export that from core and then use it in any integrations we need to port. I copied the approach here from how Lukas did thecultureContextintegration (ref), not sure if he had a specific reason in mind not to use this. Wdyt?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.
sounds good to me (exporting this and using it). FWIW the approach from lukas and in this PR are not bad I just think it is slightly better (probably) to avoid creating new objects for these things all the time - and this will likely happen quite a lot if there are multiple event processors all just adding one or two attributes!