We’ll go through setting up Sentry step--step to get visibility into our frontend and backend. Once integrated, we will track and triage errors + transactions surfaced Sentry from our services to understand why/where/how errors and slowdowns occurred within our application code.
Tracking errors and slowdowns in Node + JavaScript using Sentry
Transcription
All righty, let's get started. First of all, thank you everyone for taking the time to attend this workshop. I just want to confirm if everyone can hear me. If someone can just give me a yes in the chat, that would be fantastic. Awesome. Thank you. I appreciate that everyone. All right. So today what we're going to be talking about is how we can track our user experience in our Node and javascript apps, specifically when it comes to crashes, errors, exceptions, slow page loads, renders, and all things like that, that you would be considered about if you were the developer that wrote this code, that put it out into production. Additionally, we're going to get the visibility and context that we need from the application side so that we can actually know why these issues are happening, where in the code they're happening, who they're happening to, and actually fix it and roll forward. By way of introduction, my name is Neil Manbar. I come from a front-end development background, and now I head up solutions engineering at Sentry, where I help other front-end developers and back-end developers use Sentry and know about their issues so that they can fix them, which is the exercise that we're going to go through today and I'm really excited about. So real quick, let's just go through the agenda. First, I want to demonstrate the problem. I want to show where the gaps are when you're developing a browser app that's talking to, let's say, an Express back-end, and when issues happen, where the specific gaps in visibility and context are, and why you need a true application monitoring tool within your applications. Then we'll go ahead and integrate Sentry, specifically introduce the SDK into our application. For front-end, we'll also get the source maps up so that we can get a readable stack rate, and then we will go through all of the various use cases. So we'll use Sentry to solve for errors. We'll know that they're happening. We'll get all the context that we need, the who, what, when, where, and why, so that we can actually do something about it, and we'll do the same for slowdowns as well. And then as a developer, you're putting out releases, you're putting out new builds. We're trying to do this at an ever-increasing pace. Sentry's also going to tell you how all of this comes together in terms of releases, if your release is adopted, if it's having new errors, if it's having slowdowns, et cetera. And then any of the data that we send in to the platform, we're going to be able to slice and dice and query in dashboard, and I'll go over that at the end. If you have any questions, feel free to throw them into the chat. I'll also address questions at the end as well. So why application monitoring, and why do I actually need it in my applications? Rather than just providing you guys a bunch of text, I'm going to go ahead and showcase the problem. So here I have my application, and it's basically a react frontend that's talking to an Express packet. And what I'm going to do is leave the console open. I'm going to refresh, and it looks like once in a while, it's going to crash. And there you go. And when it does crash, we basically have this unreadable stack trace. We don't really know what's going on. We don't know even if it happened, unless the user reports it to us, or we eventually figure out this is happening and then get to reproducing it, and then we get this information here. Additionally, let's say when this does work, there's slowdowns as well. So here it's slow. Is it because of the backend? Is it because of the frontend? Is it because of my rendering code? Is it because of some slowdown at the database layer? I don't know. So let's go ahead and add some items to cart, and then we'll go ahead and check out. And when we do that, there was also some slowness, and it looks like there was an error as well. So, what I'm going to do now is kind of recap what happened here. So if we take a look, first thing, we're left with an unreadable stack trace. It was minified. We don't know what was going on, and we didn't even actually know the error in the first place. Same with the slowdown. We didn't even know about the slowdown unless the user reports it to us, and then we reproduce it, and then we have to look through all the profiling tools and all of that type of stuff. And then additionally, there was an error with the slowdown as well. So on the front end, we don't have the visibility we need, and we're stuck to reproducing. And then on the back end, if we're not using an application monitor tool, we end up having to dig through logs, assemble queries, and then piece this together from the outside rather than the inside of the application. So let's go ahead and showcase what a developer would actually want and need when it comes to this type of stuff. You would need the context. So you need an SDK that lives in the code, that's sending stuff up, and then you're alerted when there is an issue, your team knows about it, and then we can get the application-related context of who, what, when, where, and why that I'm going to show you that sentry surfaces. And it would be great that we could even identify which commit or code change caused this so we could get it assigned to the right developer and then push forward with this and roll forward and get back to a successful state. So this is the workflow that Sentry is going to be able to provide you. We're going to ship up errors, transactions, and sessions. You're going to be alerted when these things go wrong. Know about it, get the context you need, and then be able to roll forward. We're going to go through all this, but we're going to solve for errors. We're going to solve for slowdowns. We're going to see if our latest release was successfully adopted. We'll create some dashboards and slice and dice this data. And as a developer, I use Slack, I use GitHub, I use Jira. I'm going to show how all of these things play together as well. For those of you that are looking to follow along, I would suggest you create your own Express app using Express Generator or such tool, and same with react, you can create react app. And go ahead and sign up for Sentry. I've inserted a link here, sentry.io signup, and we'll go ahead and create two projects. I'm going to be using my own application. It's a little more involved. That's why I kind of suggest that you guys just use Express Generator or create react app and go ahead and just start from a plain brand new application. Signing up is free on Sentry, so you can just go ahead and do sentry.io signup, create an organization, and then go ahead and create projects, one for your react, one for your Express then. And before we get into all this, I'm going to highlight all of the documentation, and then I'll actually go through this exercise with you all, and I'll show how this is integrated into that Plant Store app that I was showcasing. So first, let's go ahead and just head over to the documentation. So for react, it's going to be quite simple, and you're going to see it's very similar to Express as well. But all you have to do is npm install or package or yarn add, depending on what package manager that you're using. And all you're going to have to do, and this is typically going to be done in index.js or as early as you can inside of your application, so we can start tracking those errors and start tracking those transactions. All you have to do is sentry.init, and when you create a project, you're going to be given a DSN, which is a key, and then we want errors to be sent up to Sentry, and this is the project ID. And for performance, we'll go ahead and enable our tracing integration, and we want 100% of traces spun up. Additionally, in my example, I'm going to be using the react router and Redux. I'll highlight just quickly the setup for that. And we will also want to upload source maps for frontend as well. So first, you have to be able to generate those source maps. It can be done typically with a flag, like I think it's source map or dev tool, just making sure that your build process is outputting them, and then go ahead and upload them to Sentry. There's a few ways we can upload them. You can use our webpack plugin, which is really easy. Just go ahead and install it, and then go ahead and specify it. In my example, I'm going to be using our CLI tool, which our webpack plugin uses behind the scenes directly, but all we have to do is basically Sentry CLI upload source maps. I'm going to highlight all of this in just a moment as well. Let's go through these instructions for node real quick. So if we go ahead to node, and then let's go to express. Once again, very similar. npm install. And then what we'll do is Sentry init. We'll do... We'll attach our request handler for performance here, and then our error handler as well. And we're set to go here. So let me go ahead and showcase this in my application. So here I mentioned I have a react application that's talking to an Express backend here, and here it is. And we'll go through this side by side with Sentry. So I already have an organization here, but you would go ahead to projects, and then we can go ahead and just create a project. Go ahead and select react. And we will be prompted with the instructions to install. So here in this case, just to save time, I've already done some of this, but I will highlight that it has been done and where the integration points are. So here I have installed these two packages, and then if we go to index.js, here we can see Sentry.init, the PSN, and that was created as part of creating this project. And here I have the stuff for performance, and I want 100% of transactions being sent up. I also want Sentry to know about what releases all of this data is coming from. As a developer, it doesn't help if you have errors or slowdowns in the last two days. You want to know that it happened in the last two releases, that it's still happening. And same with the environment. I want to know that it's happening in production or whether it's happening in one of my earlier environments so I can then do something about it. And I mentioned that we have to upload those source maps. So that's what I've done right here, is create react apps if you run a production build, we'll produce a source map. Here we're just uploading them to Sentry, and you're going to go ahead and create an auth token as either an environment variable or pass it through so that we can shoot these up to our Sentry organization, specifically that relief, and that's kind of what's going to unite all of this data. So when an error comes in, it has this relief, it has source maps associated with it, we'll apply that transformation and get a clean stack trace, which we'll then use for our grouping. And I'm going to go into all of that in a moment. On the express side, here is my package.json. We've included the packages here. And then in my server.js, what I'm doing is sentry.init, dfn, environment, and release, just like we saw earlier. And this is for performance, we want 100% of transactions being sent up. And that's really it here. One thing I forgot to highlight is that here for the frontend, if you're using a Redux, we do attach that context onto our events if you're using our integration. And here, that is right here. I'm also using the router instrumentation as well so that we can attach onto that and auto instrument accordingly. So after all of this, what's going to be done? I'm going to go ahead, once again, back to the documentation and just highlight what's going to be set up. So if we go into here and then go into react, you can see that we'll automatically report errors and exceptions within your application. And then if we set up performance, we'll also create a new transaction for each page load and navigation event and child spans for backend requests. And you're going to see a bunch of stuff as well, and I'll show you this in a moment. But basically, whatever is happening in the browser will be attached as a span, and we'll be able to understand what was going down. And similarly for Node, this will surface errors and transactions. In addition to each request coming into the backend will be a transaction, and all the activities within there will be spans. And I'll show you this. And we have database integrations and such as well to show you what's going on there. So now that we are integrated, and if you all are following along, basically run all of those npm installs and sentry.init, copy pasting the code from here should actually work. And then you're also presented the code to create an error so that we can then see if everything is wired up properly. But now that we are integrated, we're now going to have errors sent up to Sentry, transactions sent up to Sentry. We'll also have sessions sent up. So that will help us know if someone entered the app and had a healthy exit or crashed and crash free sessions went down to 95%. And we want to debug that. And then Sentry knows about our environments and releases. And on the front end, we'll also upload those source maps. So what does this all look like after it's wired up? Here I have an application that I already have sending traffic to. But you can see that here are the crash free sessions being sent up. Here are transactions being sent up. And we can display those and go into the specific views in just a bit. And then we have errors being sent up. But this helps understand exactly what's happening. Sentry knows about all of these releases. And we'll go through alerts a bit later. But long story short, the true power of this all in one view. Here we see that we dropped down to 95%. We can go ahead and highlight that data set. And we see exactly the errors that impacted that. So now what we're going to do is go through the various workflows here. Let's solve for errors. I know I showed you a little bit at the high level glance here. But now we're really going to get into it. When it comes to errors, slowdowns. And then as a developer, I'm going to show you if I put a release out there, how I know it's properly adopted and what's going on with it. And then we'll assemble some different queries and dashboards. And I'll show you how integrations plays into all of this. So first, let's go over here. And let me go ahead and do you all remember this error that I had earlier on the home page? So if I wasn't using Sentry, I'd have to reproduce and then eventually get to this. In this case, I am using Sentry. So what I can do is now automatically, I'm going to be notified that there is an error. There we go. And looks like there was a range error. And now this takes me directly to the Sentry issue. And this was an unhandled error on the front end. I can see exactly the who, what, when, where, why. Looks like it was a range error. It happened X amount of times, for Y amount of users. Started about 14 days ago, as we can see from this graph here. It's been flaring up over the last 24 hours accordingly. This first introduced in this release, it'll happening in this release. It looks like it's happening mostly on Chrome. And here's a custom tag, which I'll show you later. You can set, but it's happening to my most important customers in production on these releases. And if I want to get into all the event specific data, I can cycle through that right here. Here are all the tags associated with it. And we see who exactly it's coming from. And here is probably the most important part for an error when it comes to a developer, the stack rate specifically. So if we weren't using something like Sentry, this is what we'd eventually see. This obfuscated minified code. But since we uploaded those source maps to Sentry, we got to the readable code. And then we're even showing you the context or the lines exactly where the error happened, the stack trace and the code context for each of these frames. And we can go down through as necessary. And some of these are libraries. So we don't want to see those. So we can do app only. And these are the relevant frames and developer will want to see it. So here it looks like an error was thrown on errors.js line 14. And underneath that, we have breadcrumbs. So this is what happened prior to hitting the errors. So here Redux was doing its thing. There was some console logging and this happened on a launch. So there's not much, but I'll show you another example tomorrow. But we'd also see XHRs here, clicks and other interactions. You can see all of the other contexts that Sentry was able to capture, including the Redux state, any of the user agent information. And we're going to be associating this with transactions, which I'll show you later. But long story short, as a developer, I now know the who, what, when, where, and why. And I can fix this. I can resolve it. I can ignore it. Or if I never want to see it again, here are some of the steps I can take. But if this was something that was actionable, I'd want to fix it and go from there. All right, so this was just a basic unhandled error on the front end. Let's increase the complexity a little bit. So here, what I'm going to do is let's go ahead and debug why the checkout was broken. Was it the front end? Was it the back end? And exactly what's going on here. So when I click Checkout and Submit here, there's an error. What's going on specifically? Let's go here. And once again, we're going to be alerted in just a moment. Just to save some time, I'm going to go in here and really figure out what's going on. So here, it happened X amount of times, affecting Y amount of users. Looks like we did not get a good response from the back end. And you can see what the user was doing here. So it looks like some things were clicked on in the products list. And then eventually, looks like it issued a request to our back end, which returned to a 500, which bubbled up to our front end as such. And that's what we're looking at here. So this is an issue that manifested on the back end, but also surfaced on the front end because we weren't able to get a good response. And since I'm using Sentry on both my front end and back end, I can just go in here and then click the Related Error. And now, within one click, I'm on the front end to the back end. And I see exactly what happened. It looks like we were trying to buy a bunch of items, and we did not have enough inventory for that product. So an error was thrown. And fixing this issue will actually alleviate the both. So you can see, as a front end developer, I was able to hop from the front end to the back end and see exactly what was going on. And I see that Ignace asked, it would be great to have variable values in the stack trace. So we do do this for Python and PHP, where it is achievable, but it's actually very complicated in Node and javascript Lint. But the philosophy of Sentry is we want to be able to attach everything that we can. And if there was variable values, we would see a Show More, and we could click that, and it would show that as well. I'll actually show a Python example at the end. But here, once again, I'm in ExpressLint ServerJS, line 177. And this is exactly why this happened. Maybe I have to handle this better, or add some inventory so I can start selling again. But probably we want to handle this better and handle it gracefully on the front end. And fixing that would fix the two. And as a front end developer, I knew exactly what happened. They started on the checkout. There was an error on the checkout, and there was an error on the back end. And that's actually what produced all of this. All right. So right now, what we've done so far is just go through issues so far. Let's now go through errors, or let's now go through performance. So specifically, we're debugging an unhandled issue on the front end. Then we debug a more complex example that was due to the back end, but manifested on the front end. Let's now debug that slowdown. So if you all remember, what I'm thinking about is when we pulled an application and clicked products, it was really slow. Is this the front end? Is this the back end? Is it a combination of both? I don't know. But in this case, I'm using Sentry. So what I can do here is, one, if I don't have a loop set up for this, I can just go into the performance tab here. I'm going to go ahead and select my front end project here. Let's start there. And transactions are being sent up to Sentry. And we also leverage Web Vitals if they're available here. So what I'm concerned about here is the product standpoint. And I see that the user remisery index is pretty high here. It looks like it's taking about seven seconds to load. That's great. Let's go ahead and filter down. I can see some of the related differences here. And just to stay consistent to this usage here, what I'm going to do is pull up this transaction summary. And I can see the duration breakdown here is taking about nine to 15 seconds to load, especially when it comes to a P95. I can go ahead and toggle Web Vitals. And if you're not familiar with Web Vitals, this is basically largest contentful paint, first contentful paint, and first input delay, and some of these metrics that browsers provide outside of just basic transaction duration information. So that you actually know when the front end loaded and it was usable and it finished shifting and was actually usable so that the user could move on with their next steps and application. So here what we see is that there are a bunch of LCPs, which is the one that I'm using here, that are super high in the seven seconds. I'm going to go ahead and filter on that here. And just for kicks, what I'm going to do is browser name Chrome. And let's go ahead and pull some of these transactions up. But on the transaction summary, we can see what's going on here on the aggregate, just like we saw on the issues page. We have all the tags here. And here cutting to the chase, I can see that most of the time is being spent on an HTTP request. And Spendtree is even identifying that right here. So it looks like this suspect span, this HTTP request is taking a lot of time happening quite often. And a lot of time has been spent there. Let's go ahead and drill into this. So I'm going to click here, and now I see exactly everything that happened on the browser. So this is when I loaded up the products page, page load, the browser did its thing, imported some resources, reacted to the thing. Here it started the nav mounting for that component, and then products, which is what we're interested in here. And now we can see it took a very long time, specifically 86% of the time. And after that was loaded or retrieved, then it looks like it was rendered and the largest contentful paint check failed here. And here we see it clearly as day. Here's the red marker. Here's the HTTP request. And here's everything else that happened in the browser as well from all the browser actions, resources being imported, react doing its thing. We can see the DOM content also being loaded. And I'm using Sentry in the back end here. So I can actually just click this and click view transaction and go directly there. But better yet, I'm just going to take a step back. I can actually just uncollapse this right over here and see exactly what was happening. So this is the back end transaction in line here under the span on the front end transaction. I can see it reached expressed. It looks like we did a bunch of sequential querying. And this over here is the reason why this entire request was slow and we failed the LCP here. So I have all the context regarding the slowdown in one page here. It looks like we have a couple of questions I think I might have missed. What happens if the production code is minified? That's why you want to upload your source maps in regards to the issues. For performance, that's not going to matter here. This is actually stuff that we auto instrumented into. It looks like there was another question as well. Is there any way to send that data from Sentry to Google Analytics? Yes, there is. We do have service hooks and data forwarding and things like that, but we can show you. So just wanted to get that out of the way. But going back to here, once again, just to summarize, here is the products page. Loaded, issued a request where 86% of the time was spent. That's why we failed the LCP. And here we can see exactly what was going on. We just uncollapsed it and got all the information. And we'll have the breadcrumbs and all the other additional information here. So what we're looking at specifically is a transaction right here. All right, let's actually do one more example. And this one's going to be a little bit more complicated. Remember that when we click Checkout, there was a slowdown in addition to an error. So let's go ahead and debug that. So what I'm going to do is just go to the front end. So let's go to All Transactions. This, I believe, is the checkout transaction. And I can see, once again, all the information here. Specifically, what I want to show is this is the front end checkout transaction. It's taking x amount of time. There's an HTTP request happening. And here are the related errors associated with that as well. So once again, these transactions are slow and are impacted by these errors. We have all of that in one page. But let's go ahead and drill down into this. So here, let's actually go into here. So now, if we click this, remember, clicking here takes you to the back end error. But we can actually go into the transaction by clicking here, and directly go into the back end or downstream transaction as well by clicking within here. All in all, if we click View Full Trace, we see exactly what happened. There were two transactions. And both these transactions had errors. And this was the full picture here. And we can seamlessly go from each one of these to each one of these so that errors and slowdowns are in the same platform, as frequently errors have something to do with slowdowns because there might have been a retry, et cetera. But now I know the full picture. All right, so that's great. So so far, I showed how we can monitor errors, how we can monitor transactions, and how we can figure out what's causing them, and then get all the context of who, what, when, where, and why, figure out what's causing the slowdown. Is it the front end? Is it the back end? Is it the browser doing its thing? Is it my front end application code? And next, I'm going to go into releases. It looks like there was another question, which I can address. Yeah, you saw that user emails are displaced. Is there a way to anonymize these to be GDPR? Yes, there is. So you can do this on our server side end. It's saying that if you ever see a user tag, go ahead, anonymize it, mask it, remove it. We do have all of that scrubbing and all that type of stuff on our end. And you can also do that within the client side SDK as well to make sure it never gets sent over the wire. But absolutely, that's cool. All right, next, let's go ahead and monitor a release and then figure out what's impacting that release. Is it having some errors? Is it having some slowdowns? So once again, I'm going to go into Sentry. And I'm going to go to releases here. And I recently put out a few releases. I'm going to go ahead and query by that. I think they were something like this. So here, I'm querying by semantic versioning. And you can see that 20% of my users are still on this release. And 80% of users are on this release. I have a 14-day view here. You can see that this was taking traffic. And now this one started taking traffic. It has such crash rate. It looks like I regressed a little bit. And it looks like there were some new issues introduced as well. So let's actually go ahead and debug this release here. Also debug the views. But here now, I see all of the session information. And I can go ahead and drag and drop this. On the right-hand side, I have the aggregate adoption in terms of sessions and users. I can see how this is going in regards to crash for users over time. I see when this code was released. And specifically here, I have the session information across all releases, this release, if it changed. And I can see other metrics as well, new issues that were introduced in this release. So this probably has something to constitute with the decreased percentage as well. And I can see all of those errors being surfaced and being aggregated here. And then I have the failing transactions here as well. I can also view slow transactions, any of that, all in one place. So here, what we're doing is we've united all the data in terms of a release. And we can understand if it's being adopted properly or if it's not, what's actually impacted. Jump straight to the issue. Jump straight to the stack trace. Or jump straight to the transaction. And then go ahead and debug from there. So that is release help. So now what we've done is show how Sentry surfaces errors, surfaces transaction, correlates them, also shows you all of this in a release perspective so that you know what's going on as you're pushing your code out there. We all know we're trying to accelerate release cycles. So the more we put out there, the better it is for the user. But we have to be able to monitor that, especially when it comes to web. Next, I'm going to showcase that we can query and slice and dice any of this data to really figure out what we want to. And we can set alerts on it, do all of that good stuff, and pin it as a dashboard. So I want to go through two use cases here. So first, let's go to Discover. What I want is I want to understand which type of my customers are having errors. And then I want to get a browser breakdown of it. And let's figure out what those most popular errors are. And this is just to kind of showcase you the power of what we can do with this data and how we can query this. So here, I'm in Discover, which is basically our query builder and visualizer here. I'm going to go ahead. And let's actually just start. And right now, I'm querying all of my projects, all of my environments. And what I'm going to do is I only care about errors right now. So let's do something like this. And I also want to make sure these are ones that have this tag. And it's a custom tag I've set. Also, if you're interested in setting a custom tag, it's very, very basic. But more or less, it's Sentry.setTag. So if we go into here and then Customize Tags, I'm doing it in my code. But it's just Sentry.setTag, customer type. And let's go back into here, Customer Type. There we go. And now, let's go ahead and just define the columns according to the customer type. And let's just get the total count of them. And let's for kicks, why don't we just do count unique users as well? There we go. So it looks like they're pretty well spread out. That's great. And we can also confirm that by doing something like this. What I'm actually interested in is let's just take the enterprise users. These are the ones paying us, let's say, the most amount of money. I want to debug what's going on here. Let's see how they're having an experience on all the various browsers here. So I can go ahead to Changes, Bam. It looks like that's such. Most of them are using Chrome, it looks like, and having errors on that as well. I'm interested in that data set. So let's go ahead, add that to filter. And clicking here will also add it to filter. So here you can see it now. And now what I want to do is actually view the title of the errors and actually just view the issues as well. And we can see exactly what's going on and then be linked into the data set as well. And now let's say I wanted to set an alert for all of this. You saw some of the issue alerts firing earlier. But we have the power to even set metric alerts here. So I can just go here. And I think I would have to essentially set a project. There we go. And then create an alert. Let's just do that. And I can go ahead and set any threshold. And let's say I want to be Slack, PagerDuty, et cetera. It can all be done here. Very, very easy. Specify all that. Additionally, if I wanted to add this to any dashboards, I could do that as well. I'll get into dashboards a bit later. But so far, I queried the error data set. I'm going to do one more use case here. And let's go ahead and query our transaction data so that we can figure out the failure rates of transactions. And the failure rate is usually dictated by if it has an error and the response that it gives. So let's go ahead and first just filter down on this. So let's just say event type.transaction. Cool. Let's go ahead and just look down. And you can see how easy it is to construct all these queries. I don't have to know about query language or anything like that. Let's go ahead and just do transaction. And let's do failure rate here. And let's just start from there. And here, I'm actually just going to start with my back end app. There we go. And I can see that the checkout transaction is failing quite often. That's interesting. Let's figure out, is it happening in all the various releases? So let's go ahead, add that to the filter. Let's go ahead and change this to release. And let's go ahead. And now we can see all of this data in regards to how it's been behaving in all of the various releases. And we can add that to a dashboard or, once again, create any different alert. But now we know exactly what's happening. It looks like it's happening in these three releases in the last 14 days. And it's been hovering around 75%, which is not good. We should probably get in front of this and figure out what was introduced in 1.0. So I'm not going to go ahead and add these to dashboard. But I'm going to go ahead and just show off a few quick dashboards that really show the true power of all of this data. So right here is a front-end template. I'm going to probably want to view some front-end data for that. Let's do that. Here we go. And we can see all of our issue data, the browser breakdowns. We can see how all of this would be grouped by issues or grouped by URLs to figure out which URLs are impacted. We can display this in a big number, a map, any other sort of visualization. And here is transactions, issues, web vitals all in one place. And we can go ahead and customize any of this as well. So similarly, if we wanted to do a back-end one, you would be interested in some of that information, but also throughput, app decks, all of that type of stuff, and failure rate. And that's what we see here. Once again, you can pin from Discover to dashboards and create any of this and query any of our data set so that you can get the appropriate views. And last thing that I wanted to show here is ecosystem. But before I do that, it looks like there are some questions. If an error occurs when the application is running, will there be a real-time alert? Yep, exactly. So what's going to happen, let's say the application is running. There is an error. Sentry is going to capture that. We'll attach to the global error handler, flush out that error to us asynchronously so we don't block anything within the application. We'll aggregate that error, source map it, process it, aggregate it, persist it, and then our alerting will fire accordingly. So you'll be notified within seconds of it happening. And I think I showcased some of that earlier when I caused an error. And you saw that I pulled up Slack. And within a couple of seconds, I had been notified that this is going on. And then I actually pulled up the relevant sentry issue as well. All right. So we went through errors. We went through transactions or performance. We showed how we can monitor a release and see how it was adopted. We constructed some queries, showed off a little bit of dashboards, even showed a little bit of metric alerts as part of that. And that all stemmed from Discover. Last, I want to show how all of this can come together in your workflow. So let's say I'm a developer. I'm using GitHub to store my code and as a repository system. I'm using Slack for notifications and just chat. And let's say I'm using PagerDuty for incidents as well. And I'm using Jira for issue tracking. So let me take this. Let's say we had an alert fire, as we saw earlier. And that alert pointed us to this issue here. Let's actually show how all of this comes together. So first, we had Slack alert us. That takes us to the issue. Or we could have had PagerDuty do the same. And there's a bunch of stuff that you can do from within a Slack alert. We can resolve, ignore, assign, all that type of stuff. But long story short, you want to get to the context of who, what, when, where, and why. Let's take a look at this. It looks like this is why it happened. I think someone talked about StackTrace variable values. So here it is in Python. You can actually see the variable values at that point in time for each of the frames and see exactly what was going on here. And it looks like, and this is my favorite feature of Sentry, we integrate in with the sort code management system. And we're able to identify which commit caused this error. So here it looks like Will committed this code or merged in this code, which caused this error. So therefore, Will should be assigned this issue because he's the best firefighter for this job. And he wrote this code. He knows what's going to be going on from this rich context here. And he can fix it within five minutes rather than me trying to understand what's going on. And it might take me a couple hours. Additionally, we also have StackTrace linking. I don't have it configured in this example. But you could click here, and it would take you to the appropriate line commit within GitHub as well, or line on that revision in GitHub as well. And let's say now that we know Will caused this, let's create a Jira issue for this. Let's assign it to Will. And it actually would have automatically assigned it to Will because we actually have a two-way binding with Jira. So here is the Jira ticket on the right-hand side. So if we change the assignee or if we change the state, it will also do so in the product. So let's pretend I'm Will. I just click Done. Bam. Now we'll see that this is done within Sentry as well. And it would have done it as well. So from alerting to the deep context to the commit that caused this, getting the right person involved so that we can stabilize this. And you can even say fixes this Sentry issue, and will automatically mark it as resolved in that release as well. So long story short, we want to make sure the developer gets notified, has the context they need, has the information they need. They can trace it. They can fix it. They know what commit caused it, get the right firefighter on the job, and go back to development or playing racquetball or whatever it was that you're doing. So that is mostly what I had for today. So I wanted to showcase how we can use Sentry for knowing about our errors, getting the context we need for errors, transactions and performance, know about our releases as well, query our data, and integrate into our entire workflow. And now I just want to open it up for questions. And I see that there are a couple of questions in the chat room, so I'll address those first. So can you use Sentry for CICD? So Sentry is a application monitoring tool. So when you deploy into any of your environments, Sentry will tell it you know that you're having these slowdowns or errors. So as part of your CICD process where you're pushing out these releases to production, to your staging environments, yep, you can use Sentry to monitor these things, detect that these issues are happening as you keep releasing. Looks like Santiago asked, is Sentry a complement of some other tools such as Datadog or New Relic? Or is Sentry a replacement for those APM tools? Good question. So Datadog and New Relic are traditional monitoring tools that are mostly used in the back end, and they're mostly agent-based. What Sentry is doing is a little bit different. We're doing this from the front end. And we're an SDK in your code that starts typically from the front end. And we're able to trace all of these things. So what we're seeing is developers are using Sentry because it fits into the workflow in their application. It starts from the user experience. And the operations team use Datadog and New Relic to monitor these back ends and some of these system level type of things. There is a little bit of overlap, but that is the major divide of where you use these things and the persona that typically uses these things. How would it work in a microservice environment? So as you saw earlier, I was debugging a 500 error. Let's say if we did have more microservices attached to this or the back end actually was more complicated, we would see more transactions here. And we would be able to trace this all the way through. So what we're doing is we're passing these Sentry trace headers, and that's being set as contacts. And our server side is then making sense of all of this, establishing the parent-child relationship and who requested to whom and what happened, and then uniting all of these transactions and errors as well. serverless? Good question. So we do have serverless integrations. And the big thing that we have to make sure about serverless is that the event is flushed out. So that's one of the changes that we made here. So we have a aws lambda plugin for Node. You can go ahead and use that. All right, next question. So for serverless, it would be the same. And it's actually even more valuable because you have less context for serverless because things just fail, and then things die, and you aren't really left with much. Ignace asks, can you set this up with Slack, email, Discord? Exactly. Email, it comes out of the box. Slack, you can go ahead and configure, and you'll get alerts, as you mentioned here. I believe we have a Discord plugin as well. And you can go ahead, if you go here, TestMemory Integrations, we can see exactly all the different things. How does it work with server-side rendering? So for server-side rendering, you would have to include all of the SDKs that you would need. So whether it's a javascript SDK or Node SDK, and then you would upload the source maps, both for the server-side and client-side stuff. I don't have all of the information regarding that, but I can follow up with you, Stephen. Just involves a little bit more configuration. Santiago asked, does Sentry provide an interface to create synthetic events or a mechanism that I can use to create kernel events to Sentry? So synthetic events, not quite. We don't create synthetic load and send that to our servers. But in regards to a mechanism that creates custom events and report them to Sentry, yep. So Sentry, all in all, is like an event ingestion engine. And you can actually create your own SDK or hit our api directly to get that done. If you go ahead into here and then go Usage, there's Sentry.captureException, which takes in an error object. There's Sentry.captureMessage as well. And you can go ahead and use that to send event to Sentry, which will then aggregate into issues. And then for transactions, anything that we don't automatically instrument on, you can go ahead and start a transaction and specify spans as well. So we give you quite a bit of control there. No problem, Santiago. Any other questions at this point in time? Hopefully, I was able to show everyone how you all can use Sentry and not have to deal with this anymore and can then in front of these problems know about them and help put out better releases or respond to releases. If we have a DB connected, will it report slowness there? Yes, maybe I could have spent a little bit more time highlighting this. But let's actually go to here. And let's actually go to Express. And I believe I had a couple calls here. Let's go to Checkout and Post. So if we go into Products here, and let's go ahead and view some of these transactions, you can see there's a DB integration here that's showing the select statements and exactly what's going on here. So here in my code, you might have seen that I had the DB integration selected. But let's go ahead and do the documentation. So if we go into here, we go into Node, we go into Express, we have a database integration for all of these. And I believe this is the one that you're looking for. All righty, let's see, any other questions? I think those are there. All righty, I want to just say thank you for everyone for sticking around the last 55 minutes and asking questions. And I really appreciate each one of you all taking the time. And last thing is, if you go ahead and sign up for Sentry, we do have a little promo code here for you. And also, if you sign up or install this Node SDK during the conference, you shall get a free pair of socks. All righty, thank you all.