Closed RChutchev closed 6 months ago
That's the 'log' from the browser's console (new sentryTrace ID only after page reloaded event)
Hey @RChutchev thanks for writing in! I think we're talking about multiple issues here:
I'm getting this (no page view)
So in this case I assume that the page that the server rendered did not include any <meta>
tags for Sentry that the Vue SDK would use to continue the trace started on the server. Just talked to @cleptric who maintains the Laravel SDK and you need to inject these tags manually (see link above).
or this (multiply events from different pages to one Event)
I can only guess here but I assume this happens for one of two reasons:
http.server
transactions are not part of this pageload and not triggered by a request from a client. Before investigating this further (suspected bleed of trace id) I'd like to rule out 1 though.Let me know if this fixes your first and/or explains your second problem.
Hey @RChutchev thanks for writing in! I think we're talking about multiple issues here:
I'm getting this (no page view)
So in this case I assume that the page that the server rendered did not include any
<meta>
tags for Sentry that the Vue SDK would use to continue the trace started on the server. Just talked to @cleptric who maintains the Laravel SDK and you need to inject these tags manually (see link above).or this (multiply events from different pages to one Event)
I can only guess here but I assume this happens for one of two reasons:
- The client application makes requests to these server endpoints and they have the same trace id. This is not ideal and we're working on reducing the "lifetime" of a traceId on the browser side. However, if these requests happen as long as your browser's pageload transaction is still active, I'd argue this is expected behaviour.
- The additional two
http.server
transactions are not part of this pageload and not triggered by a request from a client. Before investigating this further (suspected bleed of trace id) I'd like to rule out 1 though.Let me know if this fixes your first and/or explains your second problem.
Hello @Lms24, thanks for your reply.
Example user flow:
Server Laravel - creates new IDs
In my HandleInertiaRequests.php in class, HandleInertiaRequests extends Middleware i've public function share(Request $request) containing this code (log from this place in code shown on my screenshot):
$baggage = function_exists('Sentry\getBaggage') ? \Sentry\getBaggage() : null;
$sentryTrace = function_exists('Sentry\getTraceparent') ? \Sentry\getTraceparent() : null;
$data['sentry'] = [
'baggage' => $baggage,
'sentryTrace' => $sentryTrace,
];
Log::debug('SentryTrace {id} was initiated.', ['id' => $sentryTrace]);
But this ID doesn't send to the frontend when the partial page reload occurs. I can't replace because the main page is already loaded and Inertia is already initialized (createInertiaApp executed and next time will be executed only after full page reload). I added {!! Integration::sentryMeta() !!} to app.blade.php which contain
for all application's pages. But it also contains @ inertia which creates Inertia App. All other page navigations will be partial page reloads.Client JS data on page navigation doesn't send or send but is lost in a lot of events in Sentry.
Inertia JS app doesn't reload the page when the user navigate to another page. When the InertiaJS App is created, any Navigation event will be served without page reload, and only the main content will be reloaded (I mean partial reload). Only when the session is destroyed page be redirected and the app will be fully reloaded. Or manually, if the user reloads the page. In any other case user will get content without the main page reload, only vue JS 'view' will be rendered/reloaded. This is standard behavior for Inertia (Docs)
IDK how to track it into Sentry, do you have any advice for Sentry + Inertia integration or Sentry and JS applications with partial page reload?
Hey @RChutchev before we get to finding a solution here, I'd like to know if I understood your ask correctly. (Really sorry but right now, I'm not sure that I do understand it yet):
pageload
transaction is connected with the http.server
transaction in your backend? navigation
transactions (i.e. "partial" reloads) don't work correctly? I see you already created an inertiaRoutingInstrumentation
which, as far as I can tell without knowledge about intertia, looks fine. The general expectation for Sentry SDKs and how we handle pageload and navigation traces is as following (assuming tracesSampleRate > 0
and BrowserTracing
or browserTracingIntegration
is used):
op: pageload
transaction. If it finds <meta>
tags for sentry-trace
and baggage
, it'll continue the provided trace (e.g. the traceId). If there are none, the SDK assumes it is the "head of the trace", meaning it'll create a new traceId. The pageload
transaction will live until there are no more activities (usually for a couple of seconds) and then finish itself and be sent to Sentry.op: navigation
transaction. These navigation transactions are always the head of the trace, so they should always create their own, new traceId. I can only recommend using debug: true
in Sentry.init
to log out transaction and span creations to check what's going on exactly.
This issue has gone three weeks without activity. In another week, I will close it.
But! If you comment or otherwise update it, I will reset the clock, and if you remove the label Waiting for: Community
, I will leave it alone ... forever!
"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀
@RChutchev Do you have a working solution for it?
@RChutchev Do you have a working solution for it?
Hello, nope and I forget about this issue a little bit b/c was busy with another functionality.
IDK what's going on, maybe Sentry have not enough documentation for Distributed Tracing or Sentry is incompatible with Inertia (and/or Single Page Application), anyway Sentry only partially works with navigation event (that's real screenshot from production)
And vice versa Sentry working good for full page reload (I mean pageload event)
Anyway idk how to fix this issue. Also, looks like new ver. 8, is incompatible with routingInstrumentation and inertiaRoutingInstrumentation function (we're using this function to set route name for activeTransaction. Code in my first message.
I think I'll delete all custom code later and enable integrations AS IS, b/c Sentry representative cant help me with that. I provided all code below, but received recommendation: "using debug: true in Sentry.init" and spend hours to debug.
@RChutchev Do you have a working solution for it?
See also this discussion if your project requires custom routing. Perhaps Mr. @AbhiPrasad will post an update for a function that will be compatible with Sentry ver 8.
@RChutchev - we'll update the docs for better inertia js examples, it's on my todo!
Thanks @AbhiPrasad - Have you an ETA for this? Or how I can inform about the updated docs? Will you write a comment in this ticket? Thanks for your effort!
we have a general tracking task here: https://github.com/getsentry/sentry-docs/issues/9943
we'll be creating more specific tasks in a little bit, just need to sync up with the team!
@RChutchev - we'll update the docs for better inertia js examples, it's on my todo!
Thanks, that's great! I hope it will be done soon.
Sorry for bothering again, but is there some ETA (1-2 weeks, up to 2 months, more than a half year) available for the integration guide of InertiaJS? Thanks @AbhiPrasad !
A more formal guide will take atleast a couple months, the team is busy with some other projects. That does suck though - so here's a quick guide I just tested that you can try!
You can set up Sentry.init
with Sentry.browserTracingIntegration
based on https://github.com/getsentry/sentry-javascript/discussions/8528 to get distributed tracing/performance monitoring working. You can use tracePropagationTargets
to set up what endpoints/services you want to do frontend -> backend distributed tracing.
Therefore your SDK init should look something like so:
import * as Sentry from '@sentry/browser';
Sentry.init({
dsn: __SENTRY_DSN__,
integrations: [
Sentry.browserTracingIntegration({
// disable automatic span creation
instrumentNavigation: false,
instrumentPageLoad: false,
}),
// optionally add session replay - https://docs.sentry.io/platforms/javascript/session-replay/
],
// We recommend adjusting this value in production, or using tracesSampler for finer control
tracesSampleRate: 1.0,
// Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled
tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
});
// We start the pageload span as early as possible!
let name = route().current();
let pageLoadSpan = Sentry.startBrowserTracingPageLoadSpan({ op: "pageload", name });
router.on("before", (route) => {
const client = Sentry.getClient();
const newName = route().current();
if (newName !== name) {
name = newName;
// every time the route changes, we trigger a navigation
Sentry.startBrowserTracingNavigationSpan(client, {
op: "navigation",
name,
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route",
},
});
}
}
});
router.on('finish', () => {
name = route().current();
// always make sure we are using the correct route name
const span = Sentry.getActiveSpan();
const op = span && Sentry.spanToJSON(span).op;
if (op === 'pageload' || op === 'navigation') {
span.setName(name);
}
});
To link your backend to your frontend pageload, you'll need to serialize meta tags into the HTML that the SDK can pick up on. Here's a guide: https://docs.sentry.io/platforms/php/guides/laravel/distributed-tracing/custom-instrumentation/#inject-tracing-information-into-rendered-html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- Serialize span information from active span in PHP land to HTML -->
<?= sprintf('<meta name="baggage" content="%s"/>', \Sentry\getBaggage()); ?>
<?= sprintf('<meta name="sentry-trace" content="%s"/>', \Sentry\getTraceparent()); ?>
</head>
<body>
<p>This is a website.</p>
</body>
</html>
With that both set up, you should be good to go!
A more formal guide will take atleast a couple months, the team is busy with some other projects. That does suck though - so here's a quick guide I just tested that you can try!
You can set up
Sentry.init
withSentry.browserTracingIntegration
based on #8528 to get distributed tracing/performance monitoring working. You can usetracePropagationTargets
to set up what endpoints/services you want to do frontend -> backend distributed tracing.Therefore your SDK init should look something like so:
import * as Sentry from '@sentry/browser'; Sentry.init({ dsn: __SENTRY_DSN__, integrations: [ Sentry.browserTracingIntegration({ // disable automatic span creation instrumentNavigation: false, instrumentPageLoad: false, }), // optionally add session replay - https://docs.sentry.io/platforms/javascript/session-replay/ ], // We recommend adjusting this value in production, or using tracesSampler for finer control tracesSampleRate: 1.0, // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/], }); // We start the pageload span as early as possible! let name = route().current(); let pageLoadSpan = Sentry.startBrowserTracingPageLoadSpan({ op: "pageload", name }); router.on("before", (route) => { const client = Sentry.getClient(); const newName = route().current(); if (newName !== name) { name = newName; // every time the route changes, we trigger a navigation Sentry.startBrowserTracingNavigationSpan(client, { op: "navigation", name, attributes: { [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route", }, }); } } }); router.on('finish', () => { name = route().current(); // always make sure we are using the correct route name const span = Sentry.getActiveSpan(); const op = span && Sentry.spanToJSON(span).op; if (op === 'pageload' || op === 'navigation) { span.setName(name); } });
To link your backend to your frontend pageload, you'll need to serialize meta tags into the HTML that the SDK can pick up on. Here's a guide: https://docs.sentry.io/platforms/php/guides/laravel/distributed-tracing/custom-instrumentation/#inject-tracing-information-into-rendered-html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- Serialize span information from active span in PHP land to HTML --> <?= sprintf('<meta name="baggage" content="%s"/>', \Sentry\getBaggage()); ?> <?= sprintf('<meta name="sentry-trace" content="%s"/>', \Sentry\getTraceparent()); ?> </head> <body> <p>This is a website.</p> </body> </html>
With that both set up, you should be good to go!
Hello, it looks like your solution has errors in syntaxis first of all. this part
router.on("before", (route) => {
const client = Sentry.getClient();
const newName = route().current();
if (newName !== name) {
name = newName;
// every time the route changes, we trigger a navigation
Sentry.startBrowserTracingNavigationSpan(client, {
op: "navigation",
name,
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route",
},
});
}
}
});
should be
router.on("before", (route) => {
const client = Sentry.getClient();
const newName = route().current();
if (newName !== name) {
name = newName;
// every time the route changes, we trigger a navigation
Sentry.startBrowserTracingNavigationSpan(client, {
op: "navigation",
name,
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route",
},
});
}
});
this one too has a syntaxis error
router.on('finish', () => {
name = route().current();
// always make sure we are using the correct route name
const span = Sentry.getActiveSpan();
const op = span && Sentry.spanToJSON(span).op;
if (op === 'pageload' || op === 'navigation) {
span.setName(name);
}
});
should be
router.on('finish', () => {
name = route().current();
// always make sure we are using the correct route name
const span = Sentry.getActiveSpan();
const op = span && Sentry.spanToJSON(span).op;
if (op === 'pageload' || op === 'navigation') {
span.setName(name);
}
});
@AbhiPrasad, thanks for offering a solution, anyway it's working better but only partially working for me, 2 different problems, I'm getting errors in the console for
route().current();
but looks like that's happening because we're loading the non-Inertia page as an iframe. I'll think about how to fix that, but that's our application-specific problem, I think I should exclude this request from the Sentry workflow. Or maybe you know, how to exclude all iframes from Sentry recording?
The second one is weird, with the new 8 ver, sometimes Sentry records some transactions as not connected to each other (for example if the user reloads the page a new TraceID will be created, and used but only the Backend event will be recorded with this ID, and this page load event will be recorded with a new TraceID and all next events will be recorded together with this ID, but root transaction will be missing), maybe that's the same problem - our application-specific but looks like something went wrong here. See an example after some navigation...
For pure Laravel everything works good
@RChutchev The problem with route() is that ne first parameter in the callback is called also route ... so this will be a conflict. Change the parameter so something else and this problem will solve. Currently integrating and will give feedback asap
For me the solution doesn't work ... the two transactions are linked in the trace, yes .. this works ... but no replay is recorded .... and I don't know why..
@RChutchev The problem with route() is that ne first parameter in the callback is called also route ... so this will be a conflict. Change the parameter so something else and this problem will solve. Currently integrating and will give feedback asap
Nope, I'm pretty sure that this error is because we're loading the page into an iframe but this page is a non-inertia page, a request to an ordinary Laravel page will cause this error. In a pure Laravel page no route().current is set, that's the reason why we're getting this error.
If you are interested you can check the production URL that's our corp service like Linktree. Currently, Sentry v.7 is in use, but I hope the new v.8 integration will be finished this month. In the user area (the faster way to register a Google OAuth) we have a preview (right panel) that loads a pure Laravel page (non-inertia). This request causes a problem in my case.
For me the solution doesn't work ... the two transactions are linked in the trace, yes .. this works ... but no replay is recorded .... and I don't know why..
Wow, can you show a screenshot of this issue, b/c I'm not sure that that's a problem. All transactions should be connected in distributed tracing, which looks like a normal behavior. For example, when the user opens /home page in distributed tracing we should be able to see backend rendering and frontend rendering (pageload) than if the user clicks on another link (e.g. /page1) we should see http.server and pageload for this page with same trace. @AbhiPrasad Am I right?
In addition, to record a trace in the Init Sentry.replayIntegration should be enabled,
Sentry.replayIntegration({
maskAllText: false,
blockAllMedia: false
}),
Did you set up something like this?
@xyNNN I'm sorry in my email notification I saw another of your comments here but now I don't see those, I was a little bit busy with offline activity. Also, sometimes I had one or two days of internet connection problems like the day before yesterday, that country-specific problem haha. Here temperature is above +35 degrees for the night and +45 for the day, sometimes that causes an outage for the provider's backbone equipment and a planned power outage for at least 2 hours per day. Active development for our corp project is finished, and now we're live, only critical fixes should be provided according to an agreement with my customer, upgrade Sentry integration to v.8 is not a critical and important fix, b/c v.7 still working well. I hope the new version of our corporate project will be agreed upon Dec. 2024 and active development will be continued in Jan 2025.
But I'm still online and I'm pretty sure that we find a solution to implement this integration for Senty v.8 and Inertia as soon as possible, when the integration is tested and works I'll update the production server outside the range of critical/scheduled updates
Thank you very much @RChutchev
Where are you currently? These temperatures are insane.... wish you all the best wish your power supply and stay hydrated and keep safe!
At first to clarify something. The provided solution from @AbhiPrasad is for Sentry v8, right? Because the syntax for v7 is not compatible in several ways.
Thank you very much @RChutchev
Where are you currently? These temperatures are insane.... wish you all the best wish your power supply and stay hydrated and keep safe!
At first to clarify something. The provided solution from @AbhiPrasad is for Sentry v8, right? Because the syntax for v7 is not compatible in several ways.
Hi, oh sorry I missed your message, I'm currently in Egypt, yep, that's hard, thanks. Yep, power supply and outages are real problems sometimes, but I got one Energizer power bank for 50K with QC 3, and one Anker for about 27.5K (250W), and now that's okay hahaha
Hi, @AbhiPrasad, are there any updates about Sentry-Inertia integration docs, or is this the only solution you offered us earlier? Or maybe @xyNNN, did you find any solution to stable integration for Sntry and Inertia?
@RChutchev Currently not. This topic is on hold until the team of @AbhiPrasad extend the documentation how to solve this issue with Inertia.
@xyNNN, okay, but honestly, I think it will never be extended/updated.
Finally, it looks like I did it. After literally 12 h., of reading all available docs (migration guide, Node.JS, VueJS, pure JavaScript, etc), and got this work.
I'll check it out on production on the next planned release (today) and after some time (about 3-5 days) I'll text here about the results.
In case I forget, if you are interested, tag me here.
@RChutchev I would be very interested in your solution! Thank you in advance!
@RChutchev I would be very interested in your solution! Thank you in advance!
Hi, finally we tested the code, and that's working, but I've some questions about Sentry Tracing, to be sure that Tracing works correctly with this code, I'll ask the Sentry representative in the next message, but now I'll provide my example.
/* Import modules... */
import { createApp, h } from "vue";
import { createInertiaApp, router } from "@inertiajs/vue3";
import * as Sentry from "@sentry/browser";
createInertiaApp({
id: "app",
resolve: (name) => require(`./Pages/${name}`).default,
setup({ el, App, props, plugin }) {
const app = createApp({ render: () => h(App, props) })
.use(plugin)
.mixin({ methods: { route } });
const SentryClient = Sentry.init({
app,
dsn: ___APP_SENTRY_DSN_PUBLIC___,
integrations: [
Sentry.browserTracingIntegration({
// disable automatic span creation
instrumentNavigation: false,
instrumentPageLoad: false,
enableInp: true,
}),
Sentry.replayIntegration({
maskAllText: false,
blockAllMedia: false
}),
Sentry.replayCanvasIntegration(),
Sentry.captureConsoleIntegration({
// Add 'warn', 'error', 'debug', 'assert' console output types to Sentry
// and additionally possible to add 'log' and 'info' console output types to Sentry if required
levels: ["warn", "error", "debug", "assert"]
}),
Sentry.contextLinesIntegration({
frameContextLines: 50
}),
Sentry.httpClientIntegration()
],
sendDefaultPii: true,
tracesSampleRate: ___SENTRY_TRACES_SAMPLE_RATE___,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
autoSessionTracking: true,
telemetry: false,
denyUrls: [
// All browser extensions
/extensions\//i,
/^safari-extension:\/\//i,
/^safari-web-extension:\/\//i,
/^moz-extension:\/\//i,
/^chrome:\/\//i,
/^chrome-extension:\/\//i,
/moz-extension/i
],
ignoreErrors: [
// Let's ignore some output as unnecessary for us now
"@webkit-masked-url",
"debugger eval",
"Not implemented",
"top.GLOBALS"
//'Failed to fetch',
]
});
// We start the pageload span as early as possible!
let name = '/'+route().current();
console.info('Pageload: '+name)
let pageLoadSpan = Sentry.startBrowserTracingPageLoadSpan(SentryClient,{ op: "pageload", name });
// Let's mount el
app.mount(el);
router.on("start", (event) => {
const client = Sentry.getClient();
const newName = event.detail.visit.url.pathname;
console.info('On start, Old: '+name+' | New: '+newName);
if (newName && newName !== name) {
/* Navigation to other page e.g. /home -> /new-page
console.log('Location changed (navigation)'); */
name = newName;
Sentry.startBrowserTracingNavigationSpan(client, {
op: "navigation",
name,
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route",
},
});
} else {
/* Navigation to same page e.g. /home -> /home without page reload (INERTIA) */
/* console.log('Location same (same-page navigation)'); */
name = newName;
Sentry.startBrowserTracingNavigationSpan(client, {
op: "navigation",
name,
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route",
},
});
}
})
router.on('finish', () => {
name = '/'+route().current();
/* console.log('Finish - Current: '+name); */
if (name){
const span = Sentry.getActiveSpan();
console.info('On finish (trace_id): '+span?._traceId+' | SpanID: '+span?._spanId);
const op = span && Sentry.spanToJSON(span).op;
/* console.log('On finish (OP): '+op) */
if (op === 'pageload' || op === 'navigation') {
if (span){
span.updateName(name);
}
}
}
});
}
});
In this code, you should set _APP_SENTRY_DSN_PUBLIC__ and SENTRY_TRACES_SAMPLE_RATE___, for test hardcoded values can be used as well.
In your app.blade.php file add this code
use function Sentry\getBaggage;
use function Sentry\getTraceparent;
and this in your <head>
<?= sprintf('<meta name="baggage" content="%s"/>', getBaggage()); ?>
<?= sprintf('<meta name="sentry-trace" content="%s"/>', getTraceparent()); ?>
As a result, you will get something like this on the pagelaod event and on navigation event
Some values, requests, and queries were masked because my customer would not be so happy if I published real production screenshots, hahaha. Because some of the customer's websites are now under attack (small, about 1000 req/min) but anyway we wouldn't like to give any additional info about internal infrastructure.
Hi, @Lms24 could you please participate once again? b/c Mr. @AbhiPrasad has ignored us since 6 June'24.
It looks insane as a company representative to provide a demo JS code that contains at least syntax errors, and some errors in your own functions (span.updateName, for example, it was span.setName), but okay. Here's the link: https://github.com/getsentry/sentry-javascript/issues/11362#issuecomment-2148484699 to his comment.
This comment contains my real example related to this Sentry-Inertia SDK integration: https://github.com/getsentry/sentry-javascript/issues/11362#issuecomment-2400733402 based on AbhiPrasad's example.
Finally, now we have time to move to ver. 8, and looks like it's working, but I've some questions, about Sentry Tracing behavior with Inertia especially and I am not sure that behavior is absolutely correct.
1) Is that correct behavior to create a new transaction on the navigation event at all and in Inertia especially (/pageA -> /pageB)? For me it looks a little weird to crate different transactions on startBrowserTracingNavigationSpan b/c the navigation event doesn't fully reload the page only partially (https://inertiajs.com/partial-reloads), that's InertiaJS. But according to these PRs https://github.com/getsentry/sentry-javascript/issues/10634, https://github.com/getsentry/sentry-javascript/pull/10656 looks like that's correct behavior, okay, I just wanna be sure.
2) Is that correct behavior to create a new transaction on partial reload (yep, that's the same navigation event) but the user is still on the same page (/pageA -> /pageA, GET request /enable-something)? For example, in this case, a user on /page-A clicks a Button (e.g. Create2FaCodes) which starts an Inertia GET/POST/DELETE request to /do-something, which causes partial reload (e.g. Show2FaQR or Show2FaRecoveryCodes) but the user is still on /page-A, and only a part of the page will be changed (some parts are deleted or/and added). Now Sentry creates TraceID for /page-A (pageload) and adds an http.server and that looks like correct behavior. But when the user clicks the Button on Sentry a new TraceID will be created with navigation and http.server, but that looks a little bit weird. See my previous comment with screenshots.
For me, trying to fix something and integrate it without fully understanding how it should work is not as good an idea. Lms24, I will be so appreciative of your answers.
@xyNNN Also, I forgot to give additional comments about this part of the code, because, the "else" branch wasn't present in Mr. AbhiPrasad's code example. This part can be simplified for production use, all 'if, else' can be deleted and use only code inside as a router.on('start'... function code, but I keep it because that's same page navigation event (e.g. user clicks on the menu to the current page and it's cause a partial reload) and that's available in our project for now. Some users can delete the "else" branch if the same page navigation isn't in their project (e.g. clicking on the current menu option doesn't cause a partial reload).
if (newName && newName !== name) {
/* Navigation to other page e.g. /home -> /new-page
console.log('Location changed (navigation)'); */
name = newName;
Sentry.startBrowserTracingNavigationSpan(client, {
op: "navigation",
name,
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route",
},
});
} else {
/* Navigation to same page e.g. /home -> /home without page reload (INERTIA) */
/* console.log('Location same (same-page navigation)'); */
name = newName;
Sentry.startBrowserTracingNavigationSpan(client, {
op: "navigation",
name,
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route",
},
});
}
Hi everyone, hey @RChutchev
First of all, no-one is ignoring you on purpose and I'd politely ask you to refrain from insinuating that we're doing that. On the contrary, Abhi went above and beyond and provided you code as a starting point for a framework we don't even officially support (as in, no docs). Likewise, I don't share the sentiment that it's "insane" that we provide code with syntax errors. I'd rather argue it's deeply human (and a sign that we're in fact not chat bots :) ). Please understand that we (JS SDK team) deal with an incredible high load of issues (~100 per week as of late) to work through. Moreover, your issue was closed, so our internal alerting system about new replies isn't notifying us, leaving it up to our private GH notifications.
General update on Inertia: We still don't have docs. It's on our radar but we have to make hard priorization decisions every day. I'm sorry about the wait but at the same time can't give you an ETA.
Getting back to the issue, I believe the open questions for me to answer are here:
Is that correct behavior to create a new transaction on the navigation event at all and in Inertia especially (/pageA -> /pageB)?
I wrote this already in a post above somewhere but I do believe that a partial reload should be covered by a navigation
transaction, if it behaves like a SPA "soft" navigation. This means that usually, the Browser's History state (i.e. route) changes and we want to track this, along with any child spans, with a navigation
transaction.
Is that correct behavior to create a new transaction on partial reload (yep, that's the same navigation event) but the user is still on the same page (/pageA -> /pageA, GET request /enable-something)?
I'd argue this is up to you to decide :) Generally, our routing instrumentations do create a new navigation span because as you outlined, even a navigation from A to A can cause new resource loads, server request, etc and we want to trace these requests and connect them frontend to backend. Since you're writing your own routing instrumentation here, you can handle this as you please. There's no right or wrong here, just what the respective routing instrumentation author thinks should happen.
There's one thing that's currently a bit unexpected in the last screenshot you posted above: The pageload
transaction and the navigation
transaction are part of the same trace. Given that the pageload
transaction happens after the navigation
transaction, I guess this means that somehow startBrowserTracingPageloadSpan
is called for a partial reload? Not sure. To be clear, this is not impacting behaviour negatively, it's just a bit unexpected for me to see. But if you're fine with it, it's totally okay to leave things as-is.
Hope this helps!
Hi, @Lms24!
All right, first of all, I want to say thank you for your professionalism and your speed of response.
1) All right, got it, that means we have gotten the right behavior as a result. 2) Okay, I asked about Sentry's point of view for this function (I mean how this should work out of the box), and I got it, thanks. 3) Yes, about the last screenshot, yes, if you mean 'preview' event, that's iFrame loading with a non-SPA page (Laravel blades + with JQuery) that's our project-specific, and totally fine if we've got this into one trace with a SPA pageload/navigation event.
The bottom line is that the variant I provided above works correctly, and has some settings specific to us, but @xyNNN, and anyone else, feel free to ask about integration using this code. I'll try to help in whatever I can.
PS: I do not want to debate with you, but a response time over 4 months is not a deeply human thing to do, and this is my opinion and I am allowed to have it. About syntaxis errors in code, yes, that's a deelpy human part of this, you're right, but means that he didn't check/test this before the post. In advance, I have no criticism of you, Mr. Lukas. If you (I mean Sentry staff, and you on behalf) cannot accept well-founded criticism towards staff, then politely forgive me. Moreover, I didn't close this issue, this issue was closed by Sentry staff, is am I responsible for that? FYI: I (like everyone non-staff here) have no right to reopen issues on GH in your repo.
After upgrading from version 7 to 8 (finally, GitHub Dependabot updated us to the new 8 version, because of security issues), our application was broken in all parts (admin and user areas) where Sentry was added. My client has requested twice to change Sentry to NewRelic (I discouraged the transition because of the lack of some features like User Feedback). I really hope that the next updates in the future will be nonbraking and bring us only new functions.
PPS: I apologize in advance for the possibly harsh manner of my comments, I do not feel well, I am on sick leave with a body temperature above 38 degrees Celsius, and a suspicion of new COVID bla-bla-bla, with limited access to the European level of medicine in the country where I am currently located. I don't wanna be rude, but everyone wants to get a reply at least once per week.
@RChutchev Thank you very much for your implementation, it works very well! Now the backend and frontend issues are connected each other. Thanks! How can I give you a tip for it? And get well soon!
@RChutchev Thank you very much for your implementation, it works very well! Now the backend and frontend issues are connected each other. Thanks! How can I give you a tip for it? And get well soon!
That sounds good! If you have any further questions, feel free to text me. Yes, please. Thanks.
@RChutchev Thank you very much for your implementation, it works very well! Now the backend and frontend issues are connected each other. Thanks! How can I give you a tip for it? And get well soon!
That sounds good! If you have any further questions, feel free to text me. Yes, please. Thanks.
Thanks mate! And what you mean with "Yes, please. Thanks" - the tip? And if yes, where I can give you to it?
The only issue is that now when I throwing an exception on backend site, this will generate in 2 Sentry issues which appears on the same trace. The one for the backend where the error are thrown. The other one from axios the http library which is the issue for the frontend that a request fails ... and there the replay is linked. But I don't want the issue for the frontend, because it's only a backend issue ... Do you know what I mean?
@RChutchev Thank you very much for your implementation, it works very well! Now the backend and frontend issues are connected each other. Thanks! How can I give you a tip for it? And get well soon!
That sounds good! If you have any further questions, feel free to text me. Yes, please. Thanks.
Thanks mate! And what you mean with "Yes, please. Thanks" - the tip? And if yes, where I can give you to it?
The only issue is that now when I throwing an exception on backend site, this will generate in 2 Sentry issues which appears on the same trace. The one for the backend where the error are thrown. The other one from axios the http library which is the issue for the frontend that a request fails ... and there the replay is linked. But I don't want the issue for the frontend, because it's only a backend issue ... Do you know what I mean?
Any time. Yep, exactly. I mean "Yes, please" - the tip, and thanks to "And get well soon!"
I'm not 100% sure I got it, can u please attach a screenshot for a better understanding? Because that should be something like this, Yes, I know that for the frontend but should be the same. One issue for one backend issue, if this issue does not cause fronted exception, etc. You should check the console in the newly created issue and SDK info (like Name), and in Event Highlights check the "level", is it the same? Please provide all information that you can and, maybe that's required to call Sentry staff again.
I have seen in my Sentry two different issues for the same error, but one was something like an "Alpine Expression Error: " and the other one was a real "SyntaxError: Unexpected token", did you mean something like this? The first one is a warning The next one is the error One issue includes another one... yes it looks like that's the same issue, but one has a warning level, and another one has an error level, looks like that's not so convenient, but that's correct behavior.
Thanks for your feedback, attached a screenshot that's describes my problem. On the right side you can see that on this trace are linked two errors. The second is the real issue, where the exception was thrown backend site. The first was is not a real issue, because it's only the http client on client side that getting the HTTP 500 response ... it's the same and not a specific frontend issue. But the replay is linked to the first error. I would like to have only one issue, with the real exception and the replay should be linked to this one. Is it now clear?
@RChutchev And where can I give you a tip? You haven't enabled sponsorship at GitHub. Do you have another way to get you a tip? Thanks in advance!
@RChutchev And where can I give you a tip? You haven't enabled sponsorship at GitHub. Do you have another way to get you a tip? Thanks in advance!
Oh, hahaha, there was some misunderstanding. I wrongly understood your first sentence. I understood you meant 'tip' like 'advice' in your first message. Okay, that's absolutely unnecessary, but if you really want to, I can enable that in GitHub, I so appreciate that.
That was a high body temperature, lol. Sorry for the misunderstanding (:
Thanks for your feedback, attached a screenshot that's describes my problem. On the right side you can see that on this trace are linked two errors. The second is the real issue, where the exception was thrown backend site. The first was is not a real issue, because it's only the http client on client side that getting the HTTP 500 response ... it's the same and not a specific frontend issue. But the replay is linked to the first error. I would like to have only one issue, with the real exception and the replay should be linked to this one. Is it now clear?
Hi, sorry I was a little bit busy. I'm back at my on-site work after a COVID-related illness.
Yes, I got it.
That's a test exception from your backend (Laravel).
I think you added this from the Sentry doc or some example when setting up a Sentry log coming from Laravel.
Just try to search This is a test exception
in your all Laravel code (with IDE, choose along all project files).
It looks like that's coming from some PHP file (controller or provider, I think), I hope it's only one result will be found.
Anyway, let me know about the results.
Thanks for your feedback, attached a screenshot that's describes my problem. On the right side you can see that on this trace are linked two errors. The second is the real issue, where the exception was thrown backend site. The first was is not a real issue, because it's only the http client on client side that getting the HTTP 500 response ... it's the same and not a specific frontend issue. But the replay is linked to the first error. I would like to have only one issue, with the real exception and the replay should be linked to this one. Is it now clear?
Hi, sorry I was a little bit busy. I'm back at my on-site work after a COVID-related illness.
Yes, I got it. That's a test exception from your backend (Laravel). I think you added this from the Sentry doc or some example when setting up a Sentry log coming from Laravel. Just try to search
This is a test exception
in your all Laravel code (with IDE, choose along all project files). It looks like that's coming from some PHP file (controller or provider, I think), I hope it's only one result will be found. Anyway, let me know about the results.
That was my test exception, which I added to check if the error tracking works in conjunction with replays. The problem is that for one issue (the exception in the backend), two errors are logged. The frontend error is actually completely irrelevant because it’s only logging the 500 error from the backend… but the replay is linked to it. Ideally, I would only expect the backend error, and the replay should be associated with that.
Does that make sense? ;)
@RChutchev And where can I give you a tip? You haven't enabled sponsorship at GitHub. Do you have another way to get you a tip? Thanks in advance!
Oh, hahaha, there was some misunderstanding. I wrongly understood your first sentence. I understood you meant 'tip' like 'advice' in your first message. Okay, that's absolutely unnecessary, but if you really want to, I can enable that in GitHub, I so appreciate that.
That was a high body temperature, lol. Sorry for the misunderstanding (:
Please enable it ;)
Thanks for your feedback, attached a screenshot that's describes my problem. On the right side you can see that on this trace are linked two errors. The second is the real issue, where the exception was thrown backend site. The first was is not a real issue, because it's only the http client on client side that getting the HTTP 500 response ... it's the same and not a specific frontend issue. But the replay is linked to the first error. I would like to have only one issue, with the real exception and the replay should be linked to this one. Is it now clear?
Hi, sorry I was a little bit busy. I'm back at my on-site work after a COVID-related illness. Yes, I got it. That's a test exception from your backend (Laravel). I think you added this from the Sentry doc or some example when setting up a Sentry log coming from Laravel. Just try to search
This is a test exception
in your all Laravel code (with IDE, choose along all project files). It looks like that's coming from some PHP file (controller or provider, I think), I hope it's only one result will be found. Anyway, let me know about the results.That was my test exception, which I added to check if the error tracking works in conjunction with replays. The problem is that for one issue (the exception in the backend), two errors are logged. The frontend error is actually completely irrelevant because it’s only logging the 500 error from the backend… but the replay is linked to it. Ideally, I would only expect the backend error, and the replay should be associated with that.
Does that make sense? ;)
Okay, looks like yes, and it makes sense. Maybe that's two different errors, one reported by one part of the application and another one by another, maybe it is one error reported by different catch methods, is it better to contact you directly? Are you using WhatsApp or something like that?
@RChutchev And where can I give you a tip? You haven't enabled sponsorship at GitHub. Do you have another way to get you a tip? Thanks in advance!
Oh, hahaha, there was some misunderstanding. I wrongly understood your first sentence. I understood you meant 'tip' like 'advice' in your first message. Okay, that's absolutely unnecessary, but if you really want to, I can enable that in GitHub, I so appreciate that. That was a high body temperature, lol. Sorry for the misunderstanding (:
Please enable it ;)
Okay, thanks, I turned it on :)
@RChutchev Yes ... they are reported by two parts of the application, but when I disable it (the frontend error) the problem is that the replay is not linked anymore.. it's linked to the frontend issue and not the backend issue where the error occurs .... perhaps @AbhiPrasad @Lms24 have an idea?
Sure I've WhatsApp but I don't want to paste my number here in public :P
@RChutchev Yes ... they are reported by two parts of the application, but when I disable it (the frontend error) the problem is that the replay is not linked anymore.. it's linked to the frontend issue and not the backend issue where the error occurs .... perhaps @AbhiPrasad @Lms24 have an idea?
Sure I've WhatsApp but I don't want to paste my number here in public :P
Okay, no problem you can text me directly from my personal contact page.
@xyNNN, I received the notification, thank you so much for the tips ;) And, as more convenient for you, please add information about SDK for both reported issues from Sentry SDK, here or via WhatsApp directly.
Hi @xyNNN iiuc, you only catch the frontend error because you want the actual backend error linked to the replay, correct?
By the way, the frontend error looks like it's coming from SentryIntegrations.httpClientIntegration()
. By default we don't catch http responses with erroneous codes.
As far as I can tell from the trace screenshot, the replay is started before the navigation
span, right? When you start the navigation, you probably make some fetch
requests to the backend where the server is running. You can try opening your devtools and check for the baggage
http header in the request. If a replay was active at this time, it should contain a sentry-replayId
key (or something along these lines). The receiving backend SDK should actually pick up this header and add a replay id to the error so that it can be linked.
Let's try to see if part 1 (baggage containing the replay id) works.
Thank you @Lms24 for your fast response. I checked the baggage header and can't find replay id. Also on the backend http request which results a exception the replayId is not present in the baggage header. My configuration is defined that a replay should exists when a error occurs, replay session rate is 0.1 by default (see configuration attached). And yes you're right the other error is thrown by the http client integration (Sentry.httpClientIntegration()). I've removed it and know I've only the correct backend error but without linked replay.
sendDefaultPii: true,
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
autoSessionTracking: true,
Is there an existing issue for this?
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/vue
SDK Version
@sentry/vue@7.108.0 , @sentry/webpack-plugin@2.16.0
Framework Version
Laravel Framework 10.48.4
Link to Sentry event
No response
SDK Setup
Steps to Reproduce
event.detail.visit.headers['baggage'] = sentryDataOnStart.baggage;
andevent.detail.visit.headers['sentry-trace'] = sentryDataOnStart.sentryTrace;
to my js file fromprops.initialPage.props.sentry
and added this code to the public function share in HandleInertiaRequests in the Middleware file.Expected Result
Actual Result
I'm getting this (no page view)
or this (multiply events from different pages to one Event)