-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(utils): Add parameterize function
#9145
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(utils): Add parameterize function
#9145
Conversation
Lms24
left a comment
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.
Hi @AleshaOleg thanks for opening this PR!
What you have until now looks promising but it seems, we're still missing a crucial part here to resolve #6725: We still need to process the __sentry_template_... fields in our browser and server SDKs. Happy to leave the details up to you but I think these functions need adjustments:
sentry-javascript/packages/browser/src/eventbuilder.ts
Lines 263 to 286 in c07ab35
| /** | |
| * @hidden | |
| */ | |
| export function eventFromString( | |
| stackParser: StackParser, | |
| input: string, | |
| syntheticException?: Error, | |
| attachStacktrace?: boolean, | |
| ): Event { | |
| const event: Event = { | |
| message: input, | |
| }; | |
| if (attachStacktrace && syntheticException) { | |
| const frames = parseStackFrames(stackParser, syntheticException); | |
| if (frames.length) { | |
| event.exception = { | |
| values: [{ value: input, stacktrace: { frames } }], | |
| }; | |
| } | |
| } | |
| return event; | |
| } |
Ultimately, we want to construct an Event where we populate the Message interface. @AbhiPrasad Not sure though what the difference between LogEntry and Message is though, do you know?
Feel free to tackle this in a follow-up PR. To test the entire functionality we should best add browser and node integration tests.
I think we also want to re-export parameterize from the SDK packages so that users can use them without explicitly importing from @sentry/utils.
|
@Lms24 Thanks for clarifying a bit! But still, there are some moments, which still remain not clear to me. As I got, I should add sentry-javascript/packages/browser/src/eventbuilder.ts Lines 279 to 281 in c07ab35
I should do something like this: I got this idea from the first comment in the initial issue (#6725) which refers to this Python API code: Sorry again, I'm not that familiar with Sentry API. |
|
@Lms24 any update would be appreciated :) |
|
@AleshaOleg I actually need to check back with some team members first, too. The whole |
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.
Hey @AleshaOleg I checked back with the team and now we know how to proceed. What's interesting to know is that event.message and event.logEntry alias each other in the Sentry backend so it technically doesn't matter which we populate with the {message, params} object. If both properties are specified, logentry will be preferred and message discarded.
However, to avoid breaking the Event.message type, we're going to populate event.logentry. This also means, that the Event type needs to be adjusted. You can modify the Event interface to specify that it either has a message?: string or a logentry?: {message?: string; params?: string[]} property. So basically make a mutually exclusive type definition. Also, both properties remain optional.
Also, for now, we make this parameterize function purely user-facing. So let's not call it within eventFromString (I'd argue this is already too late anyway, given that the input is just a string, no?).
What this means for this PR:
- whenever the SDKs create an event from a string (e.g. via
captureMessage), we check if the input string has the__sentry_template_...properties. - If they are present, we populate
event.logentry - If not, we populate
event.messagewith just the plain string - We adjust the
Eventtype to either acceptlogentry,messageor none of the two properties.
Does this make sense to you?
|
@Lms24 yes, I got everything. Now everything is clear to me, and I know the use-cases. But still not sure about this point:
Did you mean |
Yes, good catch, thanks! I just misstyped. It's |
… feature/added-parametrize-function
6556d54 to
7b27a1e
Compare
|
@Lms24 updated PR, does it make sense what I did? If yes, I'll proceed with a couple of tests for the |
Lms24
left a comment
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.
Yes, this makes sense to me! In addition to adding tests to the eventFromMessage functions, please also add browser and node integration tests. We already have integration tests for captureMessage, so adding a new one shouldn't be too hard:
- node: https://github.com/getsentry/sentry-javascript/tree/lms/astro-integration-keywords/packages/node-integration-tests/suites/public-api/captureMessage
- browser: https://github.com/getsentry/sentry-javascript/tree/lms/astro-integration-keywords/packages/browser-integration-tests/suites/public-api/captureMessage
We also need to adjust the API signature of eventFromMessage in the client interface:
sentry-javascript/packages/types/src/client.ts
Lines 158 to 165 in 0ffe696
| /** Creates an {@link Event} from primitive inputs to `captureMessage`. */ | |
| eventFromMessage( | |
| message: string, | |
| // eslint-disable-next-line deprecation/deprecation | |
| level?: Severity | SeverityLevel, | |
| hint?: EventHint, | |
| ): PromiseLike<Event>; | |
packages/browser/src/eventbuilder.ts
Outdated
| export function eventFromString( | ||
| stackParser: StackParser, | ||
| input: string, | ||
| input: string & { __sentry_template_string__?: string; __sentry_template_values__?: string[] }, |
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.
Can we extract ParemeterizedString from this PR as a type export it from @sentry/types? Then we can reuse it here.
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.
Tried to replace it everywhere where I think it makes sense. Thanks for the tip!
d1dce8e to
cdce21f
Compare
…e to @sentry/types
cdce21f to
e4c4d4c
Compare
|
@Lms24 I added integration tests, and now I understand better why there are still no Here is one tricky thing I did here - https://github.com/getsentry/sentry-javascript/pull/9145/files#diff-9b99586572e171cbe9f43e400ce8c631dfc032990c52e95632fc488dde6b1cf4R182 Also renamed function from And had to update to the latest |
… feature/added-parametrize-function
Lms24
left a comment
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.
Final pass - just a couple of small changes left then we're good to merge!
packages/utils/src/eventbuilder.ts
Outdated
| const { __sentry_template_string__, __sentry_template_values__ } = message; | ||
|
|
||
| if (isParameterizedString(message)) { |
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: not a big deal but can we move the object deconstruction into the if block? I don't think we need it outside, right?
packages/browser/src/eventbuilder.ts
Outdated
| const { __sentry_template_string__, __sentry_template_values__ } = message; | ||
|
|
||
| if (isParameterizedString(message)) { |
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: same here, let's move this into the if block
|
@Lms24 by any chance if you have time, let's finish this up :) Seems like very little left to merge it. I would appreciate help with tests 🙏🏻 Can't figure out what's wrong with them when running in cloud 😢 |
…o feature/added-parametrize-function
|
Hey @AleshaOleg thanks for the ping! I currently don't have time to look at this but hopefully by the end of next week 🤞 . I set a reminder. Sorry for the inconvenience. |
Lms24
left a comment
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.
Hmm I gave this a quick look and what's interesting is that the integration tests fail for CDN bundles, not when using the npm package. Have you tried running integration tests locally for CDN bundles?
yarn buildin the root of the repo (to build all CDN bundles)- In the browser integration tests directory, run
test:bundle:tracing:es6:minfor example (seepackage.jsonfor more bundle variants)
|
@Lms24 I think I found the problem. When I'm currently thinking about what to do. As I don't know the cause of why this happens, I can now propose to rewrite the parameterize function without using the tag function. But in this case, I think, we will miss the whole point of why we're trying to implement it. I'll try to figure out why this happens for bundle tests only, I think it's related obviously. Meanwhile, if you have any ideas please write them. Thanks! |
|
@Lms24 I think I figured out what's the problem with these tests, they're not running with any bundles except |
|
@Lms24 thanks, pushed one more commit. Please run tests again |
Lms24
left a comment
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.
Hey @AleshaOleg thanks for still sticking with us! I appreciate your patience, unfortunately we're very busy with tasks at the moment, making external contribution reviews a bit of low-prio. That being said, I believe this PR is currently in a state where we can merge it without it causing any problems.
However, we eventually want to export this function from the SDK packages. This will also expose it on the Sentry.parameterize object in the CDN bundles which means at this point we should remove the skipping guard in the integration tests. Again, to get the fundamental functionality in at all, please don't do this in this PR but (if you still feel like contributing) do it in a follow up PR.
Gonna approve as soon as we sort out the skipping logic :)
| import { shouldSkipReplayTest } from '../../../../utils/replayHelpers'; | ||
|
|
||
| sentryTest('should capture a parameterized representation of the message', async ({ getLocalTestPath, page }) => { | ||
| if (shouldSkipReplayTest() || !shouldSkipTracingTest()) { |
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.
I think this is not gonna be enough. We need to skip all bundle_ variants for now. These two functions won't do that.
basically like in this test:
sentry-javascript/packages/browser-integration-tests/suites/replay/replayShim/test.ts
Lines 8 to 13 in 94bc349
| const bundle = process.env.PW_BUNDLE; | |
| if (!bundle || !bundle.startsWith('bundle_') || bundle.includes('replay')) { | |
| sentryTest.skip(); | |
| } | |
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.
Thanks for the hint about skipping the test for all bundle builds.
I made changes, should work now.
Can you also explain how you are testing such functions for public API for CDN bundles? Because importing functions directly to tests will not work, and I'm wondering how I can test them. Just an example would be enough, I didn't find anything similar in browser-integration-tests. Will do it as a separate PR as you mentioned
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.
So as soon as we export parameterize from @sentry/browser, our CDN bundles will also include it as a top level function to call on the Sentry object. Meaning, CDN bundle users can call
Sentry.captureMessage(Sentry.parameterize`This is a log statement with ${x} and ${y} params`);we can adjust the integration tests to do that and stop importing it from @sentry/utils.
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.
that's generally how we test public API in the browser integration tests, across NPM package (esm, cjs) and CDN bundle variants.
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.
For a simple example, take a look at this test: https://github.com/getsentry/sentry-javascript/blob/23ef22b115c8868861896cc9003bd4bb6afb0690/dev-packages/browser-integration-tests/suites/public-api/setTag/with_primitives/subject.js
calling Sentry.parameterize should work just like calling Sentry.setTag once we export it from the browser package.
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.
Thanks, just tried also throws timeouts locally, but works with esm, cjs builds. Will do separate PR for that, and will mention you to run tests there, let's see if it will work on cloud setup. A lot of other tests also failing for me locally because of timeout for example for bundle_tracing_replay_es6_min, so I'm not quite sure if it works or not.
For now please merge it, just pulled latest changes from develop and I'll do separate PR for running tests for all of the builds and make this function available from browser API. Thanks!
Lms24
left a comment
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.
Thanks @AleshaOleg! I'm gonna merge this in for now. Feel free to open the follow up PR whenever you have time.
parameterize function
Add `parameterize` fuction to utils package that takes params from a format string and attaches them as extra properties to a string. These are picked up during event processing and a `LogEntry` item is added to the event.




Before submitting a pull request, please take a look at our
Contributing guidelines and verify:
yarn lint) & (yarn test).This PR solves issue #6725