Monitoring 101 for React Developers
AI Generated Video Summary
In this workshop, we will discuss monitoring and debugging with Sentry, focusing on Next.js. We'll cover setting up a Sentry project, configuring source maps, adding event context and custom tags, and resolving errors. Sentry helps developers quickly identify and resolve issues in their code, providing valuable context like stack traces, breadcrumbs, and session replay. Integrations with services like GitHub and Slack enhance error management, and alerts can be customized based on specific metrics. Distributed tracing allows for tracking performance issues, and session replay provides valuable context for debugging errors.
1. Introduction to Monitoring and Sentry
In this workshop, we will discuss monitoring in general, specifically for React apps, with a focus on Next.js. We'll cover setting up a Sentry project, configuring source maps, adding event context and custom tags, and more. After a short break, Lazar will talk about alerts, performance errors, distributed tracing, and session replay. We will share links and slides, and there will be time for Q&A. Monitoring helps detect and resolve issues that cause poor user experiences, such as slow page loads or unresponsive buttons. Sentry provides developers with timely information and context to fix these issues quickly. The goal is to resolve issues before users become frustrated and abandon the app. Sentry aims to detect and resolve issues as quickly as possible, ensuring most users never even know there was an issue. Some users in the chat expressed interest in using performance monitoring but find it challenging to understand what's happening.
Alright, so let's go ahead and get started. My name is Sarah Goethals and I lead DevRel at Sentry. Sentry is an application monitoring tool company. We are – hello from Germany. We are here to tell you a little bit about monitoring in general, specifically for React apps. Specifically, the example we're going to use is a Next.js app. As I was mentioning, this app is open source. It's publicly available from Portugal. Welcome. So you're welcome to check it out. We'll have links at the end for you, and we'll share these slides with you as well. You're not necessarily intended to follow along specifically, but if you want to, you're welcome to open up a Next.js app or React app in your favorite editor. I'm going to be using VS Code today, and you're welcome to try things out. I do recommend you sign up for maybe a free Suntry account to get started, but you don't necessarily have to follow along. The intention is that we'll share these slides with you afterwards, and we'll give you very actionable steps for how to do this later if you so choose. Again, just a quick reminder, this is recorded. Feel free to add questions throughout the workshop in the chat. At about an hour, we will take a short break. So yeah, let's go ahead and get started.
So this is what we're going to be talking to you about. Oh, sorry, I totally blanked. Lazar, please introduce yourself. Hey everyone, I'm Lazar. I'm with everyone here at Suntry. I'm originally from Macedonia too, just like our Archilka, but I'm right now in Toronto, Canada. Yeah, I'm excited to be here. I think this is going to be a really good workshop. I love doing workshops, especially with alongside with Sarah. So yeah. Awesome. Let's make this happen. All right, let's go ahead and get started. So today we're going to talk to you a little bit about getting up and running with your Next.js and React app with Suntry. So I'll go over a brief introduction to what monitoring is. I'll show you how to actually set up a Suntry project, configure source maps so that you can find the exact kind of code that is causing your performance or errors, performance issues or errors, And also walk you through adding event context and custom tags to make things a little bit easier and more actionable to resolve quickly. And then we'll take a short break and I'll pass it off over to Lazar who will talk a little bit about alerts, performance errors. So setting up alerts and issue assignments, a little into distributed tracing, and session replay. We'll give you a quick summary. We'll share links with you, we'll share this slide deck with you, and we'll go ahead and get started. Again, just quick reminder, feel free to ask questions there in the chat. And we will have time for Q&A at the end, or we should have time for Q&A at the end. So if you want to save questions for them, that's fine as well, but feel free to ask them throughout. All right, perfect. So I'm kind of curious if you use a monitoring tool, maybe just in the chat, share what tool you use or if you use it, you don't necessarily have to say what it is, it's okay if you don't use Sentry and you use something else. Just generally curious what folks' experiences with application monitoring. And if you want, feel free to also talk about what the biggest benefit to using it has been for you. As you do this, lots of Sentry, that's exciting.
A little bit about what monitoring is. This is a pretty hard question to answer in just a couple of slides and we really wanted to focus this workshop on something actionable. We expect that you all are developers or SREs or folks who will actually be using these tools and trying to resolve issues as quickly as possible, capturing possible errors and misbehaviors, yes. So I wanted to give just a quick, quick overview of what monitoring is. Essentially, there's some kind of poor user experience. Maybe this is a slow page load or something on the page is taking too long to render or a button is being unresponsive. There could be an actual error. It could just be a slow API call. Something that is causing a poor user experience. Some folks in the chat are also adding some other things that it can be useful for. For example, customer support team needing to understand the issues people are facing. Again, some kind of poor user experience. The user becomes frustrated. That typically leads to them immediately just abandoning their cart or switching over to a different app or getting distracted by something else because it's taking too long. Oftentimes, by the time developers realize something is an issue, maybe they're going through customer support. As I've mentioned in the chat, developers are too late for at least those folks that ran into that issue. Sometimes that can be a big problem. Sometimes you don't even know until people are complaining on some social media app or just tagging people, spamming the customer support, spamming the help buttons, etc. We might have all experienced this, I know I have. What Sentry tries to offer instead is an opportunity for Sentry to detect issues that users are facing as quickly as possible. Give those detected issues, whether they're performance issues or errors to developers as quickly as possible with as much context and information as possible so that developers can fix the issue quickly. Ideally, what happens is, yes, maybe some users will still experience the issue, but most users never even know that the issue was a thing because the issue was resolved as quickly as possible. Someone mentioned in the chat wanting to use performance monitoring more, but finding it complicated to understand what's happening.
2. Introduction to Sentry Setup
Sentry focuses on enabling developers to quickly identify and resolve problems in their code. In this workshop, we will explore a flashcard app built with Next.js and deployed with Percel. We will guide you through setting up a new React project with Sentry, configuring source maps, and adding event context and custom tags. Follow along with the provided demo repo or use your own application. Let's get started by creating a new project in Sentry and choosing Next.js as the platform. We will walk you through the necessary steps and explain the benefits of uploading source maps. Join us in the chat if you have any questions.
Hopefully, we'll talk a little bit about that as well today. Specifically, what Sentry likes to focus on is the ability for developers to take action. I said this a couple of times already, as quickly as possible, know what the problem is, know where the problem is, know who on your development team can resolve the problem, alert that person in the appropriate way to alert them, depending on how your team or company operate, and enable them to fix and redeploy as quickly as possible. Whether it's broken lines of code, crashes, busted API calls, we try to focus on being developer first to give you answers, not just clues. We want to demonstrate a little bit about that today. If anyone has a question on that, please feel free to ask in the chat.
Otherwise, we're going to start exploring some of this in the actual app. We're going to do a demo for you. This is a live demo with actual code and an actual Sentry project, so knock on wood that things don't go too haywire. But of course it probably will because that's how demos work. I hope the demo guys are with us today. Hopefully, it's getting a little windy here. I'm here in Washington state and it's not raining yet, but it is a little windy, and I'm using a Starlink for my Internet. Sometimes when it's a little windy, it blows my Internet away. That's how Internet works, right? We're going to be walking you through a flash card app. This was built with Next.js, and it's deployed with Percel. You can see the GitHub link here, and I'll paste this in the chat for you if you want to check it out, and you don't want to copy all of that down. Again, if you want to follow along either with this demo repo, you will need a Planetscale account or other kind of database. I think this one specifically, is currently set up for Planetscale database, but you'll need a Sentry account with an auth token, and then the read me is pretty detailed for you. You can also use your own demo or your own application, if you want, and what we're going to do, is we're going to set up a new React project with Sentry, specifically an XJS project. We're going to configure source maps, and we're going to add event context and custom tags. I'm going to be unsharing and sharing my screen in a lot of different ways, just to kind of walk you through all of this.
The first thing that we're going to do is I'm going to show you the repo, just so you can see, generally, what it is we're working with. All right. So here is our flashcard repository. Again, we've got a pretty detailed readme in here. Pretty simple to get started. There's even an exampleenv file, if that's useful for you. Pretty straightforward. Now, I'm going to share my VS code. All right. So, we've got. These darn Zoom things are always in my way. There we go. I have cloned this project in VS code. Specifically, if you are wanting to follow along and do things on your own local machine, and you have a Sentry account, specifically, I'm on the no-Sentry branch, the main branch does have Sentry already set up, or rather the files and has a lot of Sentry, so feel free to either just follow along on the main repo or you can follow along on this no-Sentry repo instead if you want. I did already set my dot env with my PlanetScale DB and all that, that has already been done, but other than that, we are going to be walking you through all of the steps ideally. This isn't quite annoying, I should've set up a third monitor here. I will do that next time. Now we're going to jump into Sentry, and I'm going to create a new project even though we already have one project here, two projects here for testing. I am going to create a new project just so that you can see this project starting from the beginning. When you create a new project in Sentry, you're offered a particular platform to choose from. We're using Next.js, that's what we've written it in, but you can see that we've got a ton of support. We support over 100 languages and frameworks. You can check those out there, but we're going to use Next.js. I'm going to just leave my alerts as alert for every new issue. Lazar will walk through different alerts that we can do later. We'll name this React Advanced London. We'll keep it in that team there. You click on ''Create project'' and it'll bring this essentially docs page. I am going to take advantage of this wizard. But we do have links to the docs that use this wizard. That would be here. Also again, all of these links are in the deck that I will share with you. But you can see that you can either set it up with the wizard or you can do it custom if you'd like. There's a setup the SDK manually here as well. In addition to that, we do have a couple of things that automatically happen when you are using the wizard. One of those things is this wizard for Next.js does automatically upload your source maps. I'm actually going to be removing that at the next step just so that you can see what uploading your source maps can look like and the benefits of it. But this will do it for you. We'll talk about why having your source maps is useful in just a moment. We're going to run this wizard here. I'm just going to copy this and then I'm going to pop on over to VS Code and throw this in the terminal. While I'm doing that, I will double-check on me. I can find the chat. It's going to ask me a couple of questions. Where did you go terminal? There you are. Let me make this little bigger for you. It's asking if we're using Sentry SaaS or self-hosted. We are using SaaS for this one.
3. Setting up Sentry and Running the App
I already have a Sentry account and it opens up my browser to log me in. Then I choose the project to connect my code to. After installing everything, I delete the SentryCLIRC file and check the project settings. Now, we're going to build and run the flashcard app. Sentry takes privacy seriously and is used in various environments. It's useful for performance issues and errors. We'll introduce an error in the code and rebuild to execute it.
I'm going to say yes. I do already have a Sentry account, so I'm going to say yes. It's going to open up my browser just to essentially log me in here. All it's done is that, and it just shows a screen that says, return to your terminal to complete your setup. Nothing happened in the browser.
Then I'm going to choose the project that I want to connect my code to. So this one specifically is that React Advanced London Project that I just created. It's going to install everything that we need and everything is done and ready to go. Let me find the chat. Where did you guys go? Hello chat. Sometimes I do not like, let's see, show chat. There you are. Make sure there's no questions. Yes.
Is it okay to just do Git Clone? Yes. If you haven't experienced GitHub Template Repos, basically it allows you to fork it, but it's not really a fork. It's like, because a fork implies that you're going to push code back into the main original repository, it allows you to basically make a copy on your own account. That's usually the best. There's a button on there that says use this template or there should be. We have our Sentry. That's it. That's all we had to do to connect our new Sentry Project to our Next.js Project. It's really simple and fast and easy. It makes being an advocate at Sentry boring sometimes. But let's go ahead and like I mentioned, I do want to delete this SentryCLIRC file because this is what uploaded the source maps and I want to clean that up so that we don't have them, so you can see what is going on here. I think I also need to double-check that my.env wasn't set. I think, yeah, perfect. Then we also need to go into, I will share my screen again. We will go into the project, you can actually see it. Here's our projects. Here is the React Advanced London project inside of Sentry. You can see nothing has happened yet because we haven't done anything yet. It's waiting for events. We can get some tours, we can do all the things. If we go into the settings for this project, and we pop down here into source maps, we can see we don't have anything here because we haven't built yet. If you use the wizard with Next.js for Sentry, it'll automatically upload the source maps once you build. Since I deleted the Sentry CLI RC file, now when I build it, shouldn't automatically upload them. I just wanted to make sure that nothing had happened yet. This is where you will find it though. We're here in this project. Now we're actually going to build and run some things. We're back in VS Code here, and I'm just going to build.
Part of why we wanted to do this end-to-end and have you actually see how to set everything up and run everything is because, I don't know about you, but for me, it is very frustrating when people are like, you just click this button and it works and then it doesn't because there was another side thing that they didn't tell you about. So we want to show you all of that. Should be almost done building now. If there's any other questions while we're building, there we go, let me know. Okay, so we're gonna run this now and we're gonna there we go, and open it up and this is our flash card app. So this is a very simple app where it has these flashcards with a question and answer in a category. You can delete, you can update, you can create new ones and you can also practice. How easy is it to set up Sentry with GDPR in mind? Very easy, so Sentry takes privacy very, very, very seriously and I think we actually have a good blog post about that. Lazar, can you? Yeah, I can look for it, yeah. I think I just found it. Here's one of the blog posts specifically around our Sentry Replay, which is pretty difficult for privacy concerns in general privacy concerns in general, because Sentry Replay, as Lazar will show you in just a moment, allows you to see what users are actually like clicking through, which is a challenge, when if like, if they're putting in information. And so, yeah, we do take privacy very, very, very seriously, but you can check that one out. And I think there's other ones if Lazar wants to try to find some. Where's Sentry mostly used and what would it benefit you for? Yes, great question. So Sentry is used front end, back end, mobile, basically anywhere and everywhere. One of the things Lazar will show is distributed tracing, which is being able to trace an issue from a like user clicking and having it not respond all the way down to the API calls, database calls. We just released query issues as well for database queries. And yeah, it's useful for any kind of performance or just regular errors, performance issues or regular errors that are happening on your app.
Okay, so this is our flashcard app and gosh, sorry, the star zoom controls. Okay, here we go. So this is our flashcard app, looks great, still no issues. We can look into our project here. Nothing should be happening. We've got a release because we built, but nothing's going on here, so we are all good. Now we're going to actually introduce an error in our code, rebuild, restart and then execute the error essentially. So the way that I'm gonna do this is I'm gonna come down here into this file and this is where we handle any kind of updates to a flashcard. So first of all, we wanna make sure that the question exists, it's not a length of zero. The answer is also not a length of zero and that there is a category ID.
4. Debugging and Issue Resolution with Sentry
I'm going to remove a line and allow submitting or updating a flashcard without a question. We'll rebuild and restart, but encounter an error with no Sentry Auth Token Configured. Let's start the flashcard app, open DevTools, delete a question, and try to update it. The error in DevTools is not helpful, so we check Sentry for more information. After some searching, we find the issue related to the incorrect DSN configuration.
I'm going to remove this line here and I'm gonna allow us to essentially try to submit or update a question without having a question, or a flashcard without having a question. Maybe you just accidentally did this. So, we're going to, I'm just gonna, boop, rebuild here and then we will restart it. And, you can see here, in the terminal, this error, no Sentry Auth Token Configured, so source maps will not be uploaded. You can find information about that here.
We will do that in a minute, but it's always useful to look at what is being printed out when you build. All right, let's go ahead and start this up. We'll head back over to the flashcard and we will refresh it. And, I'm also going to go ahead and open up my DevTools here, Okay, and I'm going to delete this question and I'm going to try to update it. You see we get an error in DevTools, but this error isn't super useful. It says ad update. It does say handle update, but I don't have any other information really. I mean, none of this is super useful. So, now I'm going to go into Sentry and see if I can find something that's even more useful. Maybe, maybe.
So we've seen the release. I think I see, takes a minute. Refresh, refresh, refresh. Come on. Let's go. Come on. Let me see if my issues show anything. I think this only be, is this my nine minutes ago? That was too long ago. There's, oh, nope, that was the flashcard one. Let's go back into the React Advanced Pundan. Oh Lazar, why is this issue not showing up yet? I guess give it a minute. Yeah. You change the DSN. Right, there we go. Is that it? No, that's still just the release. Are you ready for the issue? There it go, oh, wait. It should be. Maybe it's better if you go to the issue sort of like scroll down. I think there's a list. Yeah, let's do that. That's still the other one. Nope, that's still the old one. Did you do like the DSN in the.env? Oh yeah, you know what? I think I might have, I forgot to update it to the other project, you're right. Yeah. Okay, let me stop sharing for just a second. Yeah, so what happened is the DSN is a string. It's like a connection string for a database. And that tells the Sentry SDK to point everything it captures to this URL. And if you noticed previously when Sarah was setting up the wizard, it asks us, it asks her, are you using Sentry, the SaaS on sentry.io? Or are you self hosting Sentry? Because that's also a thing. You can actually self host it on your own servers. And in order for the SDK to know where to send the data that it captures, the DSN is here to provide that info for the SDK. So basically if you set a wrong DSN, you'll be sending errors and data and performance metrics on a different place, not in your project. And the problem was that the wizard does everything correctly, but I had manually changed it to a different project. So that was all me. All right. Let me just redo this real quick. When you try to know more than the wizard, it's probably not a good idea. Good wizard, bad user, exactly. All right. I'm just rebuilding here. Oops. And yes, the Sentry Config file was configured properly with the correct DSN. But again, I manually changed stuff, so. All right. I'm gonna reshare here. And we should be good to go. So let me go ahead and refresh this again. Okay, so we're gonna go ahead and delete this question. And we're gonna click update. We're gonna again see that this error is not super useful. And then this time, oh, there it goes. We're gonna go into projects. And here. And now we've got our third release. And I think I see that error.
5. Uploading Source Maps and Error Resolution
We add source maps to get actionable information about errors. Sentry helps quickly identify the root cause of specific errors, allowing for faster resolution. It provides notifications for errors in production and allows for attaching code owners. Sentry is not just for monitoring, but for actionable fixes.
There it is. See, it shouldn't have taken so long. That's why I was like, what is going on? All right, let me show this chat again because it keeps disappearing on me. Okay, so let's go ahead and go into this error. And we can see that we've got an IP address, we've got the version of the browser I'm using, the version of the operating system I'm on, some other additional information, but this information here is not super useful. There usually isn't a delay. That's why you just noticed it actually did show up fairly quickly when it was configured correctly, but yes. So this is not super useful information. This is about as useful as the information was on the developer tools in Chrome. So now what we're going to do is we're going to add the source maps. Alright, perfect. Any questions about how that got set up? So this is, and actually maybe we should just walk through this a little bit more. This is the issue view for Sentry. So what's nice is that issues will automatically get grouped together when they're the same type of issue. So you can see that there's only been one event that caused this issue for one user. But if we were to, let's say, go into this one and delete this question and attempt to update, well now it's still frozen because it got caught in a loop because of the way the code is working. But if we were to refresh, and then go ahead and delete this one, and update, then when we come over here and refresh here, we have two events for the same user that are causing this issue. And if we look at all of the issues in the issues tab, we can see here again that, well three events, probably because I clicked on that extra button, but for one user and click into it and get all of this information. You can also click into the specific events and see them. This probably needs to be refreshed. Well, I don't know why that's not showing up differently, and you can also pass through to each of the different events. So we've got, this was the one that was seven minutes ago, this one was the one that was three minutes ago, and you can see if there's anything that's different related to these types of events. Sorry, two seconds. Love you. This happens because for every error, we capture all sorts of data, like for example, the device info, what is the device that the user is using? Is it a mobile, is it in the browser, what's the version of the browser as you can see? So there's very user specific data for each of the errors. So we grouped them, but we still need to provide different pages for them so that you can actually make an assumption like, okay, it might be Firefox only or this issue happens on Firefox and Chrome. So that's the reason. So you can see here, the, what is closure is the one we just did. The, what is a component is the one that we did before. So you can also see that if it's showing up on multiple pages, what environment this is. If this was dev environment or production environment you can see which release it was a part of. So these ones were all a part of the same release. This was a part of the previous release. Yeah, lots of different information. You get the error that was given. You can actually open up the replay but I'll save that for Lazar. And you get this list of breadcrumbs as well. It shows you everything that was happening as it goes. What I do wanna show you though is the source maps cause I do think that that is particularly useful. What is the benefit of self-hosting Century? I mean, basically if you want to be able to not have it be run by us and use it essentially for free. All right, so now we're going to go in and we are going to upload source maps. The benefit of uploading source maps is that you actually get the line of code that is useful because again, our goal is to make it very actionable for developers, not just let you know that there's an error we can have like logs let us know if there's an error. We want it to let us know there's an error, tell us immediately, send this to the line of code potentially assign a code owner immediately and alert that person. That's the goal. So we're gonna come in here into our terminal again. We're gonna go ahead and clear that out and we're going to run the source maps wizard. So if you didn't run... So let me see. If you didn't use a wizard and you didn't set up source maps then you could run the source maps wizard. Yeah, if you didn't know, Sentry is actually open-source. Oh, it's making me log in with Okta, hang on. It's gonna get you a link. Do we want to continue with this wizard? So this is saying you have already uncommitted, un-tracked files. It'll create and update files, that's fine. We are using Sass, we already have a Sentry account. It's gonna go ahead and open that up for us. We can go back to view issues, come back over here, and we're going to make sure it's on the right project. It's Next.js, do we want to run the Next.js wizard? So if you wanted to, you could start with the source maps wizard and if it detects that you are, or if you say that you were using Next.js for example, it'll say, would you like to run the Next.js wizard? We don't need to, because we already did. So it basically just tells you how to add to your config file, but we already have that. We are not using CICD and it's successfully updated. So now we need to build, because if we go into our project settings here for the React Advanced London, settings and source map. Oh, over here. Blue, there you go. You can see still nothing is there. So now we can build. When we go to the inspect page, there we can also see errors. So what errors specifically shown by Sentry? Yes, so Sentry isn't just for kind of grabbing the errors, but rather for being able to quickly identify the root cause of specific errors so that you can more quickly fix it. So instead of just having to open it up on the inspect page and like, see them all and do it, you would actually get notified immediately when errors are happening in production, assuming that you're in production, and then you would get alerted and Lazar will show you a couple of the other features where you can actually attach co-owners and things like that, and yeah. So it's not just monitoring, but rather like actionable fixes. Does that make sense? If you have a better way of describing it, Lazar, feel free.
6. Event Context and Custom Tags
We've uploaded source maps and are now going to run things. We can see the error history and access the source code. When using Developer Tools, it's not as useful in production unless you know the exact steps to recreate an error. Having links to the source code is the most useful information for developers. Source maps won't point to the exact line of code in third-party libraries, but they will point to the line of code where the library was called. Now we will walk into event context and custom tags. We want to add more identifiable information about users, such as user emails, to the context. We create a const data to get information about the current session. Inside the update, we add the user's email address to Sentry's custom context. This allows for more useful errors and can be customized to fit specific needs.
I think you covered it, yeah. Yeah, it's more about being actionable. Okay, so we've uploaded source maps and now we're gonna actually run things. And we're gonna go back to our page over here, and let's go to another one, what is a promise? Delete that, update, get an error. Head over to here, we'll go ahead and just go into here. We have four releases. Gonna refresh this. We'll see we had this error, but that was seven minutes ago. Let's go ahead and refresh again. Should pop up here soon. Oh, I didn't, hang on one second. I just need to make sure I didn't rewrite or overwrite something. Monitoring and manipulating. Or monitoring and like, letting you know what I'm writing down, or monitoring and like letting you know what needs to be manipulated. Right custom error messages for Sentry. Oh, let me just see if, okay. So that one was working. Did I do something dumb again, Lazer? Sorry, I was replying in the chat, what happened? No, you're good. I'm just trying to figure out why I didn't, why I'm not getting my error. Oh, there it goes, one minute ago, here we go. Okay, so this one was categorized differently because now we have actual access to our source code. So we can actually see that this is where the error was, it was created, triggered, and we have a whole history of it. So it was this update here that caused the error and then that was happening from when we were trying to actually update something in the flashcards. So this is much more useful than when we look at it for the previous one, here, where this one is very similar to what we see here in our, it's almost like a century. Yes, exactly, dudum-dum. So when you're using your Developer Tools, first of all, you're not gonna be on your user's computers. So when you're in production, Developer Tools isn't as useful unless you know the exact steps to recreate some kind of error. Second of all, even if you had Sentry set up but you didn't have source maps, still you're only kind of getting, I mean, you still get a lot more information. You get all of this kind of data from all of your users. It gets grouped together. You can see how many users are being affected, how many times users are getting affected, et cetera. But the most useful information here, in my opinion, as a developer is actually having links to the source code, especially because you can even attach Jira or Git Hub or any of your other issue tracking software that you use and have it like automatically create issues depending on certain thresholds or create an issue from here. And you can do some automatic alerting and assignments, which Lazar will go into. You've got your breadcrumbs here. You basically have everything you need. What's the difference with Rum? I don't know if I understand that question. Is it like a real user monitoring? Will the source map pointer will work the same if the error is triggered by a third-party library or package used? Will it point to the line of source code within the project or the actual error triggered in the node module directory? That's a good question. So if you don't have the like, if it's a third-party one, it won't point to the exact line of code in the third party, but it will point to the line of code where you called that third-party library. So then you would know that that's where it, no problem. Okay, so, that's basically source maps. Now we have stack trace. We're gonna walk into event context and custom tags now. We're gonna go back to our code. And this time One thing that wasn't super useful over here, for me, at least is the IP address. For example, if this was like a store or something and it was like very high priced items, maybe you have like fewer customers, but you wanna be able to reach out to customers if they had a problem with completing something and they didn't have enough time to complete it. Maybe they had a problem with completing something or whatever it might be. I don't know. I'm just making up stories on the fly. It would be more useful to be able to have more identifiable information about your users here. So I wanna create a custom context or an event context. I wanna add to the context around adding in user emails. And what I'm going to do is over here we're going to, first of all, we're gonna leave this commented out because I wanna make sure that we are still getting the errors. And I'm gonna create a const data to get the information about the current session. So this is just gonna get us information about the current session. Let's go ahead and do a quick fix. Okay, this is just React. And then I'm going to come down here and inside of my update, I'm going to add in that if we wanna do this beforehand, sorry, before we update, I wanna add to Sentry who the user is, and specifically, I want the user's email address. So the way that we're gonna do that is, I'm just going to say, if the session has a user and an email address, let's set the user to that email address or like set the user's information that email address to that email address. Let's go ahead and add in Sentry up here though. So we add in our import statement for Sentry. And right here, we're just saying, look, if the current session's data, like if there's data and there's a user, and there's an email address, great, go ahead and set the user for Sentry this custom context, email is data.user.email. So that's basically all we're doing here. Writing good messages. Yeah, so this is kind of tricky. We're not gonna walk into what the messages will be for users. But if you're talking about something like this, I think this is the direction that you might wanna go in, which is adding in additional context to make the errors within Sentry most useful for your developers or for yourself. So that's kind of what this is for. You can add in kind of whatever data you have access to in that current session or in that current view or whatever you're using. And if I can chime in on that. Please do.
7. Debugging with Sentry
Messages aren't 100% important in terms of Sentry. Console log isn't always helpful for debugging. The additional data captured by Sentry, such as stack traces, breadcrumbs, and session replay, provides valuable context to quickly identify and resolve issues. Adding tags or context can help filter errors and make them more actionable. Analyzing the frequency of errors and the number of affected users helps prioritize fixes. Sentry is hyper-focused on developers, providing them with the necessary tools to quickly resolve issues.
Messages aren't 100% important in terms of Sentry. That's why we captured all this additional data. So in a way, because console log isn't always helpful for you to debug stuff. That's why you get all this other data. And I would say don't struggle that much with the messages, if for example you have a try cache that you're fetching users and the cache gets hit. Say, there's an error fetching the users. But then using all of the other data, you'll actually figure it out alongside. So yeah, the message is not like the only part of the solution that you need to fix the error. The data is, I would say, even more important. But yeah. Yeah, that's what's useful is like, so full disclosure here, I am very much a console.log debugger in general. Like that is my go-to as I think it is for a lot of us. But again, we're talking production level apps. We're talking tons of different types of errors or performance issues. I mean, hopefully not, but let's be real, we all are gonna have errors and performance issues as developers. And so as Lazar said, this information that you're getting here around kind of who it's affecting, why it's affecting, how it's affecting with stack traces and breadcrumbs and session replay, this information is gonna make it faster for you to go figure out where the problem is than just having a problem is here message type thing in a log, ideally. So-
But look at the error. This errors message, what is it? It's error. Right? There. Yep. Failed. Well actually, this one does say, failed to update flash card. But then it just says, why bad request? Yeah, reason, bad request. Like it's not super useful. Exactly. Yeah, but like get the rest of the data and you'll basically see. It's the whole thing that helps you debug. Yeah. That's good. Actually did it. It's going to create a new issue. I think. Because now we added additional context. 12 minutes, 19 minutes. Hello. What happened here? You triggered the new request, a new failure. A new issue. A new error. And this time we added in the context. So it should show up here soon. Try one more time, just in case to avoid the sampling. I will say it is much harder to demo Sentry on like very simple apps that don't actually have a lot of users because things don't happen very often. There's a question. I have so many errors in Sentry right now is like what was it? Let's run that. I should, let's run that. Let's run that again. Oh, that's sort of a funneling error. It's just to really be able There's a question. I have so many errors in Sentry right now. It makes it hard to go through. There's also three months. So, so many new errors came out of nowhere, maybe a Microsoft crawler, unsure, nothing I can do about it, which is sad. So many errors. So, this is where I think adding in tags or context can be very useful. Here we go. Because then you can do some filtering through errors to make it at least hopefully a little bit more actionable. So, now you can see this was the original error from about 15 minutes ago, and then this was the new error that we just did. And now, instead of an IP address, like we had here, where it's like, I don't know who this person is, but this is their IP. Now we've got, oh look, it's this person, admin at admin.com. So, now we have additional context to this. And we can see that information down here, and we can see that it's affected multiple users, mainly because we didn't have that in general. And then you can also kind of click into here and then see if this person had a lot of different types of issues that they were experiencing. You can also watch the replay for this one, but again, I'll leave that one for Lazar. For lots of different types of errors, if you are trying to figure out which ones to focus on, you can look at how many events versus how many users, and so basically how frequently are you getting that error, but then how many people is it affecting. If it's only affecting one person, then maybe there is just something weird with what their setup is and or how they're using your application, in which case, yeah, maybe that's low-hanging fruit. You can go see and say, oh, actually, it doesn't work on Firefox or this old version of Chrome or something like that, and then you can just add in your information to say, hey, this doesn't actually work on this browser, et cetera, or if it's affecting a lot of people, that actually might be something that you want to prioritize more. So even if the event is only happening once per user, but it's happening to all users, that's likely something that you really want to focus on. The biggest thing about Sentry compared to other folks is that, or other application monitoring tools, is that we really are hyper-focused on the developers, so making sure that developers can get to that line of code, see the stack trace, see everything that's happening. Sorry, I just smacked my mic. See everything that's happening, and as Lazar will show you in just a couple minutes, be able to apply code owners, alert the developer immediately and get that issue resolved as quickly as possible.
8. Custom Tags and Issue Assignments
Custom tags can be useful for filtering through issues. Console.log is powerful but not secure. Sentry allows adding custom tags to provide additional information for filtering. The usefulness of custom tags is particularly evident in search. The workshop covers setting up Sentry, adding event context and custom tags, and filtering errors based on tags. The session will also cover alerts, issue assignments, distributed tracing, and session replay.
Also, just kind of in general, in our philosophy and how we build software, so again, I mentioned that we're open source, so we really are like built by developers for developers with developers, essentially. Okay, I'm going to finish up one last thing. This is the custom tags, and again, this can be very useful for when you have a lot of issues, like was mentioned in the chat, and you are working on trying to be able to filter through those issues in ways that are effective. Also, someone mentioned console.log is powerful, but not secure, because you don't want to reveal too much information in your console.log, so you don't want to be able to share things like user IDs, and things like that. So that is another reason, yes. Resolved error by itself so that it gets easier. Yeah, AI, that would be nice. And I think that they're... You know, it's very tricky, we're not going to dive into the question of like AI versus not necessarily right now. But yeah, that is a way. Okay, so now what we're going to do is, we're going to add in custom tags. So there are a few operations that are happening, we can update, we can remove and we can create a new. I'm not gonna go into the creating a new, but let's go ahead and talk about how we might want to set a tag for updating or removing a flashcard. So when we want to update, so here we're in the handle update function. So right down here, we're going to add in, this Century.setTag for update. So we're saying the operation that we're trying to complete is updating and we're going to do the same thing over here on the remove. So we'll go ahead and set this to remove. We wanted to, we can also add in a create one, but we're not going to, that would be over here and just kind of this handle create, but we're not going to worry about that right this second. Okay, so this will again, just kind of add additional information to make it easier for you to filter through different areas that you have in the Sentry dashboard and see those playing out. So let's go ahead and PNPMBuild. Yes, that's a great question to Sentry. Is Sentry going to, or does it already focus on visual or user experience? Like if a use effect is running five times and making something like flash on the screen. And Lazar responded, which is very interesting. I'm really excited about this. This is a user reporting widget. So basically allowing you to have something attached to your page or app that users can report something that isn't incorrect in code but is an error or an issue for users and their experience. And then those will show up just like the more code-based issues and errors in Sentry. But, and be similarly filterable in all of that. But yes, it will be a user initiated action unless we wanna use AI to run it over and over again. Okay, I started getting distracted by chat, go ahead and refresh this. I'm just gonna refresh another time and I'm gonna go ahead and go into what is a type guard? Okay, got an issue. Okay, I think it showed up already. Did it show up? Yes, okay, cool. And then here what we will see is if we maybe refresh again, 32, oh, wait, was this the same one? This was the same one, wasn't it? Okay, let me go back. So the usefulness of custom tags is particularly in the search, so you can search for operation is, what did we say, update, right? Which it hasn't triggered it yet, so just refresh again. Well, here it is, so operation update. So this is only showing the errors that are unresolved where the operation was update, and you can see if we remove this one, then all of the errors show up. If we open this one up where we did add the operation, then the tag also will show up here. Right here, so operation update. And if we scroll back through the previous events, you can see those ones don't have that tag, so it'll only update to the tags that are associated with those particular events. And again, this is particularly useful for if you have a custom tag and then you need to share it, or sorry, you need to filter by that particular tag.
Okay, so the first thing that we'll do Okay. So real quick, pretty much what we've done is set up Sentry by using the wizard, one line of code, and it got everything working for us. We built, we tried it out, we created an error, we saw it, we made sure source maps were actually uploaded the second time around. It would have been uploaded the first time had I not deleted the Sentry Cli RC file. So we make sure that it's updated, we run it again, and saw that now we were able to see a stack trace. Then we applied, or sorry, we added event context, specifically the user's email address, and custom tags, specifically which operation we were trying to accomplish, when the error happened and noticed that the errors inside of Sentry, the specific events, have that additional information if it was added after the fact.
Okay, we're gonna take a short break, about five minutes, so 9 0 8, if you are in Pacific time, which none of you are. So five minutes, eight minutes past the hour, how about we just say that. Feel free to continue to ask questions here, I'm gonna stop sharing my screen. And Lazar is gonna get set up with his, yeah, one benefit of Sentry also specifically that it's open source is that we do have a ton of integrations in general. And some of those are by us, some of those are in partnership with us, and some of those are just because we're open source and people can make them. Yeah, and you can do alerting in kind of Slack, Discord, Teams, et cetera, but you can also do integrations with like Jira and GitHub and Asana, if you use those for project management more. Okay, I'm gonna pass it off to Lazar and I'm gonna fill up my water. There you go.
Alright, let's begin. So, as Sarah mentioned, we're gonna do three more lessons until the end of this workshop. So the first one is we're gonna set up alerts and issue assignments. Then we're gonna do some distributed tracing. We're gonna explore what are like the benefits of distributed tracing and how to set up distributed tracing in Next.js. Then at the end, we're gonna do a quick run on Session Replay. What can we get out of Session Replay? And like, how can Session Replay help us debug faster, et cetera? So yeah, let's check it out. Alerts and issue assignments. We're gonna do issue assignments first. So, Sarah showcased a bunch of errors. Alright, so we can see how errors look like, what is the data that we're getting, like all of the data, but who's going to solve this problem? Who's gonna solve this issue? Is it me or Sarah? We can get in and I don't know, roll the dice, play some sprint poker, try to figure out who has more bandwidth to fix this issue. And if this is something that I caused, for example, my part of the code, as you can see, the error is in Hook slash Flashcards. So someone created the flashcards React Hook. What if that was me and Sarah got tasked to fix the error? She's either going to struggle because that's not her code. So she's gonna need more time to read and understand what I wrote.
9. Code Owners and Integrations
Code owners allow errors to be automatically assigned to specific individuals based on rules. These rules can be defined using plain text or imported from a GitHub code owners file. Integrations with services like Slack, GitHub, AWS Lambda, and more provide additional functionality and allow for easier management of errors and alerts. The GitHub integration, in particular, enables source code management, issue tracking, stack trace linking, and code owners. By setting up the GitHub integration, developers can jump straight to the relevant source code when investigating errors. Integrations with other services provide even more flexibility and options for managing errors and alerts.
Or she's going to bother me. So I'll fix it at the end of the day. But we don't want that to happen. If this happened in my part of the code, I should be responsible for that. We can't let it to chance. So for that, and this is not like a century specific thing, a century specific issue, a century just supports it. We have code owners.
So for example, if you go to your settings in your organization, go to the projects and here's the React Advanced London. By the way, if I need to zoom in, do let me know. Okay, I see perfectly fine here, but if it's too tiny for you, let me know. Here, let me just bump it up a little bit. There we go. So, ownership rules. These rules are just plain texts. And what they basically mean is whenever an error happens that satisfies this specific rule should be automatically assigned to this specific person. Right, so that's GitHub code owners file. If for example, it's exactly GitHub code owners file. If you know GitHub code owners, they can be manually added. So if I click on the read, edit rules, here's an example of how they look like. I'm gonna zoom in so you can see more. For example, if the error happens on this path, so source slash views slash checkout, I'm responsible for that. Or for example, the URL, right? If it's on slash checkout, maybe that's like an API request. Put me on that. Or for example, a specific tag is attached to that error. For example, if the transaction tag is slash checkout slash page. Again, that's me. Because for example, I'm responsible for the checkout module or anything that has to do with checkouts, right? I'm a checkout expert. If there are errors, they belong to me, right? I need to solve my own problems and errors, sorry. So, automatically assign them to me. Basically we can do this now. Go back to Issues and for example, if this error, as we can see, it's not assigned, right? No one is responsible to fix this, not yet. But if I click I can manually assign to any of the team members. But, we can create a rule just for this error specifically. So if I click on the settings here, the example, as you can see, we see the same screen, right? But this time, check it out, the example, the suggestion or this issue involves this specific file. Right, so that's what we can do. We can grab these and we can put them here in the ownership rules and maybe there's a save button. Yeah, there's a save button hiding below, we can just hit the save button and we're good. You can do that. You can use wild cards, as you can see, like star, for example, slash hook slash star, anything that's within the hooks, like I'm responsible for all of the hooks, give me all the hooks errors, right? But there's also one more interesting thing is, as I mentioned, the GitHub code owners file, which a lot of projects have. We support that as well, so if we go to project settings and ownership rules, there's a button called import code owners. And in order for us to do that, yeah, we need a GitHub integration. And now let's get into integrations.
So integrations live on, there we go, live on the organization. So one sentry organization can have integrations installed, not projects, okay? And those integrations, as you can see, include Slack. But basically, integrations give you more superpowers and allows you to connect sentry and your sentry data and alerts and everything with other services that could be relevant to your operation, right? And one user asked us if they're like alerts on Slack, there we go. We have a Slack alert. And on the right side, you can also see what that integration brings or like what is it for. Chat for alerting rules, et cetera. There's a GitHub and we're gonna do this right now. It's for source code management, issue tracking, stack trace linking, code owners. Let me show you the stack trace link real quick because you might notice that. But if we go to the error, you see this, add the GitHub or GitLab integration to jump straight to your source code. So basically you can just click and it'll open that file for us. That's also what the GitHub integration brings. And of course code owners, which we're going to do now. There's also an integration for AWS Lambda, Bitbucket, there's a Discord one. Even if you use Discord, if you don't use Slack, you can take your errors in Discord, Grafana, Teams, there we go, Vercell for deployments. There's a custom webhook. Basically you can send a webhook for each of your alerts. And if you don't use either Discord or Slack, but something third, like even not even Microsoft Teams, yeah, you can have a webhook alert you. And these are the, there's plenty, as you can see, there's like a lot of integrations. Jenkins, Travis CI at Twilio, Trello, everything, right? So let's set up the GitHub integration. As we mentioned, we use the GitHub integration for source code management, issue tracking, stack trace linking and code owners. These two are like especially cool. So let's click add install. Let me sign in. Of course, I'm going to take this here. I hate that I have to sign in on every five minutes, but that's security. All right, here's what we see. Here's the Sentry GitHub app.
10. Configuring Integration and Code Mapping
We configure the integration and authenticate it with my GitHub account. Then we add the flashcards repository and set up code mapping. Next, we import the Code Owners file and encounter an error with ownership issues. To resolve this, we configure user mappings and set up ownership rules. After cleaning existing errors, we build and run the app, trigger the flashcard error, and observe the requests sent to Sentry.
And if we click configure, it's going to ask us where do you want to install? Let's take my account. And I can only select the flashcards repository that we we're working in, right? So we'll hit install. There we go. So now we have the integration installed and authenticated with my GitHub account. So I can click here and add the repository. Adding the repository is important because that's what brings all the context to Sentry. So errors and like code maps and everything works with that in mind. So we added my repository, the flashcards repository. And what we need to do is add code mapping.
Code mapping basically is whenever an issue happens, what is the root folder, right? The root folder where everything gets reported. So in our case, let's just connect the react-advanced. Of London with our flashcards repo. So that's how we marry these two, right? This is the GitHub repo. This is the Sentry project, but these are the same. The branch is not master, it's main by default. The stacktrace root is just dot. It's the root, so our project is simple. If for example, this was a part of a monorepo, you would have to do, I don't know, source slash packages slash et cetera, et cetera. In that case, the root, the stacktrace root is not gonna be just a dot. But in our case it's a simple, it's a simple project, so we'll just do two dots. There we go. So if we go into the projects now, go to React Advanced London and ownership rules, we can actually import our Code Owners. And let me just show you how that Code Owners file looks like. We go to.github and Code Owners. This is basically it. Anything, let me zoom in just a little bit more, anything that happens within flashcards, and that can be multiple things, like that can be the page flashcards, that can be the API flashcards, that can be the hook flashcards. I'm working on the flashcards, assign me. And this is my GitHub username. Anything that has to do with categories, assign Sara because she's working on the categories, I'm working on the flashcards, right. So that is the code owners file. So let's import this and see what happens. Apply an existing code mapping. There we go, we already set up that. Here's the code mapping. It successfully found the code owners file, so let's just add it. And an error happens. There were two ownership issues with Sentry on the latest sync with the code owner file. Let's see what's that. The following usernames do not have an association in the organization Sentry dev rel. That is the user mapping. So we did the code mappings, that's cool, but we also need to do user mappings because who is at Nikola Flazor, who is at Dr. Gattles, right? It doesn't know. So we can click configure user mapping, or we can just go back to the settings, integrations, GitHub, configure, and there's the user mappings. And now we see a table where Sentry is like, yo, I saw these two users. Who are these people in Sentry? Right, in the Sentry organization, because if I need to assign at Dr. Gattles, who's that in terms of the Sentry users, right? So we can set up that user mapping here. Let's say here's Sarah and here's me. Cool, so if I go back now to the ownership rules, there we go. We see the two ownership rules ready, right? Everything that has to do with flashcards, I'm responsible for that. Anything that has to do with categories, Sarah's responsible for that. Beautiful, so let's see how this works. These are already here, right? So they're existing errors and they won't be automatically assigned. So I'm just gonna delete them so we can start off with a clean slate, okay? I'm going to build the app, and I should have done this prior to this, but still, PMPM build, PLPM start. This is gonna run the app. There we go, localhost 3000, we are ready. So if we go here and hit refresh, there's our app. Let's trigger something. Let's trigger the flashcard error. I'm gonna clean all of this, I'm gonna delete the question, and it happens because, let me just show you why, and like, what are the points where we have this? Hooks slash flashcards. There's a point where I, there's a remove, where's the, actually let me say this. Yeah, this is actually the file page, manage flashcards slot. So pages manage flashcards slot, there we go actually, it was not the hook, it's gonna points, it's gonna make the error in the hook, but here's the error, you see that? Basically, this is the handle updates function. So when I hit update and don't check that the questions length is zero, basically the input is empty, it's not gonna prevent me from updating it, but I have a check on the backend to say, okay, is the question empty? I don't care, bad request. Right, cut it out. So that's what we're going to cause on purpose. So I'm updating the flashcard with the question empty. Do that, there we go, the requests, the server responded with 400 bad requests, and we see three envelope requests from our endpoint to sentry, from our browser to sentry. These are basically, these are basically the snitches. All right, so there's a whole payload that explains and describes what everything happens. Right, here's the SDK, here's all the data, here's all the environment.
11. Issue Assignments and Alerts
As you can see, the environment's set to production because we're not running a dev mode right now. The assignee is actually me. That's the code's assigning feature being doing its job automatically for us. Let's crash the categories now to see if it's going to be assigned to Sarah. So we failed to update the category. We see the envelope requests. Let's go back now and see. See, Sarah Guttles, matching code ownership rule. Now, let's check out the alerts. Alerts mean emails, Slack messages, Discord, webhooks, and multiple emails to the team. When Sarah created the project, she said, give me alerts for every issue. But if you're working on a project at a certain scale, that might not be as productive. You can set up smart alerts based on errors, sessions, or performance. For example, an issues alert triggers when the event level is fatal or when an issue was seen a hundred times in the last two days. User experience alerts notify when a large number of users are experiencing errors. Session alerts monitor the crash-free session rate and user rate. Performance alerts provide insights into app performance.
As you can see, the environment's set to production because we're not running a dev mode right now. But all these things, we're not gonna bother reading, of course. But yeah, as you can see, it's already up there. So if we go back and hit refresh, we should see that error here.
Okay, and who's this? Who's this guy? You see that? The assignee is actually me. I didn't have to click it. That's the code's assigning feature being doing it's job automatically for us. Let's do another one. Let's crash the categories now to see if it's going to be assigned to Sarah. Hit that update there, we go, bad request. So we failed to update the category. Of course the reason is bad request. We see the envelope requests. Beautiful. Let's go back now and see. Oh, we're already there, there we go. See, Sarah Guttles, matching code ownership rule. Yeah, we also even tell you, why is Sarah assigned? Because you have a code ownership rule. Beautiful.
All right, so now when Sarah and I, right, it's Monday, so we should be at work and we just tune in, let's see what's been going on during the weekend. One of us probably pushed a deployment on Friday and we know how that ends. So yeah, I'm just gonna log in and see what's on my menu, basically, and yeah, this is something that I fix now. Exactly. So yeah, there we go, this is the codes ownership rule. So we can do that manually if we wanted to by specifying a path or a URL or et cetera, manually type it in or if we use the code ownership file for GitHub. So when an issue opens and get auto-assigned on GitHub, we can also mirror that, bring that to Sentry and do the same here. That's the general idea. So that was the issue assignments.
Let's check out the alerts now because I think alerts is at the core of what Sentry is. Alerts mean emails, alerts mean Slack messages with a tag so you actually get alerts. Get a notification. They also mean Discord. They also mean as you saw, I don't know, webhooks, et cetera. They also mean multiple emails like me, Sarah and the rest of the team. Immediately get on your feet and we got to solve this. So those are alerts. When Sarah created the project, she said, give me alerts for every issue. And if you're working on a project that's at a certain scale, that might not be as productive, right? So we talked with a fellow engineer here in the chat. They were receiving a lot of errors. Some of them were like really old. Some of them were not relevant because the user used a Chrome extension that painted the website dark always. And that extension failed and the extension is gonna cause a crash in the console and centre's gonna pick it up and that's not yours to fix. Of course you can ignore them, but what also you can do, what you can also do is set up smart alerts for them. And maybe not on every, right? So if we go to the alert's page and hit create alert, we'll be met with an interesting screen. So let's go through all of the options. There are three categories of errors, of alerts. Sorry, we can create an alert based on errors. We can create an alert based on sessions, on user sessions, or we can create a performance alert. So for example, the issues alert, it's gonna trigger an alert when the event level is fatal and we define what fatal is, right? Or for example, when an issue was seen a hundred times in the last two days, or in the last five minutes. For example, if lots of errors happen, we wanna be notified. If one or two errors happened, maybe not, it's an edge case. But if we can see a lot of errors happening at a certain time, yeah, of course, there's the number of errors, for example, 10K errors in five minutes, something's really wrong. It's not an edge case, it's actually an error in our app. And that's how we can define that. We'll create one anyways, but see, you have the critical status, above or below or equal, et cetera. You define what the threshold is. There's the user experience, users experiencing error. For example, maybe not 100,000 errors in five minutes because that can be, I don't know, that can be a DDoS, right? Causing the error, but what about users? 100K users experiencing an error in one hour. That means a lot, like a huge percentage of, I don't know, our users are experiencing an error. So there's definitely something's wrong with our app. Those are the users. On the session side, we have the crash-free session rate and crash-free user rate. So a user is a user. A user can have multiple sessions, and there's a session, right? So session rate and user rate, that corresponds to that. When the crash-free rate is below 98%, send a Slack notification to the team. That means 98% of the sessions are not experiencing an error. But that's not 100%, right? 100% means that no one experiences an error, but like 95 or maybe 80, if that's like 80, one in five users are experiencing errors. We can use the sessions alerts to get notified about that. And then we have performance, and these are really fun. Start from the top.
12. Monitoring Metrics and Alerts
Throughput, transaction durations, Appdex, failure rates, and web vitals alerts are all important metrics to monitor in Sentry. By setting thresholds and defining actions, developers can be alerted to issues that affect user experience and take appropriate action. Custom metrics can also be created based on other event data. Creating alerts for errors is a key feature of Sentry, allowing developers to quickly identify and resolve issues. By setting thresholds and defining actions, developers can be alerted to critical errors and take appropriate action. Integrations with other services like Slack provide additional options for managing alerts and notifications.
We have the throughput. The throughput is basically how much transactions are happening or like are being reported in a certain timeframe. For example, on a key page, transactions on a key page exceeds a hundred thousand transactions per minute, right? Or drops below a threshold. For example, if our users are going to the settings page regularly and they suddenly stop going to the settings page, it can mean two things. Either they're not interested in the settings page anymore or something's preventing them to go to the settings page, right? So we shouldn't get alerted. If they can't go there and they must go there or like they should go there, that's the point of the app, we should see about that. And that's like we can use the throughput for alerts for those cases.
Then we have the transaction durations. For example, a specific transaction is slower than three seconds. We know that it should take about two seconds. So we'll take like we'll add one more second for a good measure. But if it's longer than three seconds, that means something's wrong, right? Or like what's the 75th percentile response? Is it like higher than 250 milliseconds? Victoria asked, what's considered a transaction? Transaction is that envelope we just saw, right? That's the Sentry SDK, sending data to the back end to Sentry.
Okay, the Appdex. Yeah, there we go. The Appdex, so this metric is the app misery. The user misery basically. It's like a ratio of, as you can see here, satisfactory, tolerable, and frustrated requests in a specific transaction or an endpoint. So if that drops, we gotta do something about it, right? That means that the users are generally having a bad experience on certain pages. And it's automatically recorded. So for example, if some of these things you don't understand, like what is the number, you get a little chart at the top. So this is the Appdex. It's one. Sometimes it's 0.93, sometimes it's 0.88, 0.639. If this is not good enough for our standards, we're gonna create an alert that's like 0.7, right? So that's how you can, that's how Sentry can help you understand what is the value that's in normal use, basically.
Then we got the failure rates. The failure rates for an important endpoint, which is 10%, that means it's from the other side. So for example, we had the session, right, or the transaction duration, but now we also have the failure, it's not just long, it's just fails. There's that and there's also three web vitals alerts for the LCP, the FID and the CLS, because while we're here, we're also capturing these for you and we're sending them to Sentry. So you can check out how your CLS, FID, LCP. And there's also other web vitals that we're recording so you can see them. You can create an alert on them as well. So for example, if the CLS goes above 0.1, you need some work. If it goes above 0.25, you're in the danger zone. You got to do something about it. So you can create an alert and it's gonna let you know when the CLS goes above 0.25 and where, which page is struggling with CLS. And at the end of the day, we can also create some custom metrics based on other event data, like issue data, like there's a tag or there's a load that transaction and et cetera. So these are all the alerts.
What I can do now, let's create a number of errors. All right, just to demonstrate this, we're going to create a number of errors. We can see that we have zero because I deleted everything, remember? So zero number of errors. I'm going to set the one minute interval. And there we go. We actually have the one, yeah, the one that I triggered. The threshold, this is the events and it's not gonna be on the flashcards, it's going to be on the React Advanced London. There we go. These are the errors. We can pick the production environment or testing or any other environments that we have. And of course this is the event error or the event type. We're gonna keep this as an error. The threshold is can be static or a percentage change. We'll stick with static, but you can also, like, 10 times higher or lower compared to the previous period. And the period is like one minute. So we'll keep with static. And now we can define the threshold. What is critical? Critical is like five errors in one minute. Warning is like three errors in one minute. And of course, resolved is automatic, but we can also hit zero. If there are no errors, then it's resolved. Then we define the actions. So for example, for a critical status, email someone can be me, for example. Or the team, right? It can also be another member. So we can keep Sarah, right? Yeah. You can basically do that. When you have more integrations like Slack, et cetera, you'll have more options here. I didn't add them, but they're gonna be here basically. And the ownership who is the ownership is of course, the Sentry dev rel team. Save the rule. All right, yeah. Alert name. We forgot the most important.
13. Setting Up Alerts
Let's cause errors and see what happens. Sarah should receive an email alerting her about the failures. The status will change to critical as we triggered a lot of emails. This is how we set up alerts to notify us of critical issues or performance drops in our app.
Let's just call it tests. The most appropriate name. So we have the thresholds here. As you can see, the red line and the yellow line is here. There are these things. Let's cause errors now. Let's cause a lot of those. So here's one, two, three, four, five. I'm gonna hit one more or a few more for good measure. So let's see what happens. We should start seeing errors. 20 errors. All right, I'm sorry, Sarah. That was the categories. You'll, 28 errors. Okay. So Sarah should receive an email saying, yo, you're failing. You gotta do something about that. Right now it's- I definitely have an email. Yeah. Right now it's below three. Yeah, as you can see, it still haven't configured, like crunched the numbers. Should we show the email real quick? Yeah. I can show one of the emails. Is this the right email? I think so. So you can see, it gives me a lot of information right here inside of the email, some of the tags, et cetera. I can mute this particular alert straight from my email. I can open it up in Sentry. I can even set it up in Slack straight from here. So this will just take me to the integration settings and allow me to add a workspace just right from the email. Nice, thanks Sara. It's how it looks like, so let's go back. There we go. This is going to change. So it sent an email, but it's not there yet. This is going to change to the status is gonna be critical because we triggered a lot of emails, right? There we go. You see, you can already see, let me just, let's say the last seven days, if you go last six hours, we can see this a bit better. Right? The threshold critical is here. It just needs to update the status, but this is how we set up alerts. This is how we can, like, alert ourselves for very critical stuff or for performance drops in our app.
14. Distributed Tracing and Span Creation
Distributed tracing is a debugging technique that helps identify performance issues and track the flow of operations. It involves creating traces and spans to measure timing and gather information. The SDK in Sentry automatically handles trace continuation on the backend. By setting a CentryTrace header, the trace can be continued from the client side. Mutating the cache and handling errors are also part of the process. The use of mark spans and serialized spans allows for measuring specific operations and capturing relevant data. Distributed tracing provides valuable insights into the flow of operations and helps identify potential issues.
What is next? Distributed tracing. All right, my favorite. So distributed tracing. That's a tool, that's a debugging technique that helps you debug performance issues or like weird bugs that are happening in your app, maybe like, you know race condition apps, et cetera. It's not like, okay, there's a crash. It was on this line. Go fix it. It's not always that obvious. Sometimes you need to track the operation flow to see what happened before the actual error happened. And the answer is gonna be there, in the previous context. So that's what we can use distributed tracing.
That's an interesting technique and it starts off, for example, it can start off at the client side. So we're starting a trace. A trace contains spans. These spans know when they start and when they end. They know they have like a title. They have all their information like tags, et cetera. So if I open my flashcards hook and find the date function, there we go. This is where I have this set up. So, first I need to get the current scope and then I'm going to create a new transaction. Here's that transaction thing we talked about in the chat. I'm creating a new transaction called updating flashcards. I'm doing flashcards. I could add more stuff to it if I wanted to. I just kept it like this. And then we're going to bind that transaction to the current scope. So whatever happens within this scope is going to be tied to this transaction. Then we can create a new mark span that's just like a little flag making the API requests. Right, this has no timing. So we're starting the child span and then we're finishing it immediately. In order to continue because we're making an API call, we're starting the trace from the client side, and now we're going to create, like make an API request and proceed to trace it on the back end on the API. We need to continue that trace somehow. The SDK in CentrisCase is going to do that for you automatically. You don't even need to do this to be honest. I just wanted to make it obvious for you all. But yeah, this is going to happen automatically for you. You don't have to do that. But whatever, what happens is we are setting a CentryTrace header, which is basically a three value string separated with a dash. You got the trace ID and the parent's span ID. The third one is whether if it's, what was the name, process or not. But yeah, there's like a 01, et cetera. You don't need to worry about that. Usually it's always just two. So this tells us, this tells the back end, hey, here's a request that has a CentryTrace. That means the client or whoever that was started a trace on the client side, on their side. And if they're giving me the CentryTrace, I need to continue that, right? So I'm going to parse the trace ID. I'm going to grab the transaction, the, sorry, the trace ID, create a scope, bound bind the scope to that trace. And then I'm going to get the span ID and the next span that I'm going to create is going to be the child span of that one. So that's how we can continue tracing on the backend. Everything is going to be much clearer when you see it in action. So this is how we're setting the header and we are just shooting the requests. And some, you know, things happen in the backend and then we have a result back. If the result is okay, we need to mutate the cache. All right, let's see. Here's a mutating cache start, mutate the first one, mutate the second one, mutating cache end. We could do this without mark spans, I just felt like I'm gonna put mark spans. But you can create one span. And so you can do like, here's the serialized span. This is not a mark span, this is a serialized span. The operation is actually valid. And what this does is basically it starts off here. Whatever happens in between this and the finish gets measured in time. And this is how we can measure how long does the serialization happen on the client side. Maybe that's the error, right? Maybe that's too long. So we wanna measure that. And then we finished the span, because if we don't, it's not gonna be included in the transaction. So it's not gonna be sent to the backend. So it's not gonna be, you're not gonna be able to see all this beautiful data. And then we finished the transaction. In the case there's an error happening we wanna create an error span, right? Fail to update the flashcards.
15. Backend Transaction and Trace
Finish all this, both of this, and then bubble up the error. The key point is the headers of Sentry Trace, which connects the frontend and backend. We obtain the ongoing transaction on the backend and append more information to it. When updating flashcards, we see the network request and the envelope. The performance tab displays various transactions, including the React advanced London transactions. The event for the updating flashcards transaction contains the trace, showing the execution flow of the API request.
Finish all this, both of this, and then bubble up the error. So this happens on the client side. The key point right here to know is this line right here, the headers of Sentry Trace. Let me just get rid of this. Yeah, there we go. This line is important. That's how we connect the frontend and the backend. And of course this line right here. Because we have an ongoing transaction. Get another transaction and then we can attach multiple stuff to it. So let's go to the backend and see what happens there. We're gonna go to api.flashcards.slog.ts. Okay, this is a Next Reg S API handler. Nothing fancy, right? We have a slog, update this specific flashcard. We grab some stuff from the party. We try to get the session. Are we logged in or not? We try to get the user from that session, et cetera. And then we get into the handler. So this is the get one we need to put one. That's the update one, right? So instead of creating a new scope. Actually, yeah. We're getting the scope as we were on the client side but we're trying to get the transaction from it. We're not creating a new one. We're getting the ongoing transaction. That's because the SDK on the backend, on the API saw that there's a sentry trace and it already created that transaction for us. So we just need to obtain it, like give me the transaction, right? So now we can append more stuff. Like we can now glue more stuff onto it on the backend and send it back to the client. That's the general idea. So here's the transaction. We're getting the categories and then we have a category checkspan, right? Is there no category? Yeah, we wanna set the status to not found and finish it. And return an error back. We don't need to close the transaction because we didn't create it. It's not ours to close it. Again, more checks, then give me the flashcards or give me the, now let's do like a flashcard checks. All these things. And then, yeah, at the end, we don't need to finish anything. Like we finished the transaction, for example. Everything's here. So what happens now when I actually go to flashcards and update the flashcards. Hello London and hit update. There we go, flashcard updated. We saw the network request. There's also the envelope. So let's see. If we go to the performance tab here, we're going to see a lot of transactions. Not all of these are created by us, of course. But then also Sentry is really smart and it does a lot of stuff automatically for us. So what I'm thinking about, we want to want to see the React advanced London transactions at the top and check this out. Updating flashcards. If you see the others, you'll understand that this, this is something else. This is typed. All of this is just randomly got data. Okay, updating flashcards. We have an event for this transaction and that event is actually contains the trace. If we open that event, and I'm gonna collapse this now. We're going to see, what is this it? No, that's not it. We're going to see, that doesn't look like the event that I'm trying to demo right here. Let's create a new one. Demo gods, please help. Let's create a new one. I don't know what happened there, but we already get some data and I can demo it. I just wanted to show the real thing. Updating flashcards. There is the second event. There we go. No errors. This is the event or the trace, basically, the whole trace. From this list right here, let me just zoom in so you can see better. From this list right here, you can see how the execution flow went. We started with making the API request, then we did the API request.
16. Distributed Tracing and Session Replay
The update took the most time, 386 milliseconds. The whole operation flow can be seen in the chart. This is distributed tracing. In addition to trace details, you can access the operating system and other data. Let's demo the session replay. We can see the timeline of user actions, console logs, network requests, events, errors, and the trace. Session replay allows you to observe user interactions and troubleshoot issues as if you were in the same room. You can see where they clicked, console logs, network requests, events, errors, and the trace.
It returns OK. We didn't fail, so we need to mutate the cache. There's a mutate cache start. Here are the two mutations happening. Mutate cache, end, and then serializing response. On the right side, though, you can see how much each of those actions took. Mutating the flashcart slash slug took 92 milliseconds. The general flashcarts took 97 milliseconds. The whole API call took 600 milliseconds. If this was five seconds, if this was five seconds will be like, okay, we know what's wrong, right? We know that this API call is wrong, but we can dig deeper. Like if we click on the plus, we're basically going to the backend and we're seeing what happened on the backend now, right? So user find unique, and this is db.scl.prisma. Guess what? If you're using Prisma, there is an existing integration sent to the back end. Integration sentry.server.config. Now you'll see this last line. This means that any Prisma query towards our database is going to be automatically instrumented for us. We don't need to do anything. And that's why we get these automatically, right? We saw that we first tried to find the user in the session. Then we have the category and then the category check. Then we took the flashcards from the database. Then we did a flashcard check. And then at the end, we did the update. So looking at this chart, we can see that the update took the most time. 386 milliseconds. Is that too much? Is that too little? I don't know. It depends on what your database is. Is it serverless or is it not? Is it within your, I don't know, Docker network or is it not? A lot of factors can affect the time. So 600 milliseconds, in some cases, can be considered slow. In some cases, can be considered really fast. That's up to you to decide, right? But you have the info now. You can see the whole operation flow. This happened. Then this happened. Then this caused this to happen, right? The whole water flow. So yeah. This is distributed tracing, basically. And aside from this, you also get all the other data, the trace details, the operating system, where it happened, what happened, et cetera.
All right, so we don't have much time. So let's demo the session replay. Let's go to session replay. We can see that there are some session replays here. But if we were to configure this, we would need to go to sentry.client.config, which is the browser. SDK, the browser site, and we need a new integrations array that's going to have a new Sentry.replay integration. And that's it. There are like values you can configure. Replay, for example, on error sample rate. Give me all the errors but give me just 10% of all of the sessions. So, let's try... Should we trigger this or should we see... Let's actually see this one so we don't need to run this. Here's replay. There we go. So, if I hit play, we're going to see, first we see the whole timeline. We can see how Sarah clicked around the app and on the right side we can see the breadcrumbs, and they're like highlighted where we are with the execution. You see that? So, Sarah clicked twice, an issue happened, she reloaded the page, navigated twice to different flashcards, probably clicked again. You can see everything. Aside from the recording, et cetera, you can also see her console log. And this is going to be this part right here. But we don't have any logins in the app, but they're gonna show up there. Aside from the logging, you can also see all the network. And again, this is just like the Network tab that we have in Google Chrome. But to remind you, this is on production. This user can be in a different country, on a different device, you don't know them, you don't know how they're called, et cetera. But it's like you're in the same room with them when the issue happens. You can see where they clicked, how they use the app, you can see any console logs that happen during the session, you can check out all the events, and if you click on them you can see, okay, here's the request, here's what the browser sent, here's what the browser responded, like the type, the method, the status code, et cetera. It's like you're there. You can see a list of all the errors that happened on this session alone, and of course the trace. Here it is. The whole trace, starting from including the reload. So we went to the server, we invoke this get request, then we did a put, which is of course an update of the flash card, then we fetched a bunch of things, navigation happened, there's a middleware being hit here, probably for the authentication, there's a Dom event, basically where the user clicked, so you can see for yourself, a memory snapshot of the heap and the Dom nodes, maybe it's a memory issue, there you go, you'll figure it out, and of course tags, any tags for this session that describe this user session. What you can also do is go to the issues and click on the errors right here.
17. Session Replay for Error Debugging
Session replay allows you to see what the user was trying to do that caused an error. It provides valuable context and helps debug errors and performance issues.
Or maybe it wasn't this one. Yeah, maybe I deleted that one. I shouldn't have, but yeah, if you click on the replays here, you'll see that replay. So you can also go the other way, like, okay, I have an error, fail to update flashcards, let's say I don't have any idea what that means. It's too abstract for me. If I wanna see what happens, I can just click on replays and I'll see that replay. It's gonna link that replay and if I click on it, it will take me to this screen. So I'm going to see what the user was trying to do that caused that unable to update flashcards error. So I'll be like, okay, now I get it. I can see that the header is not being sent because I can see the request headers, et cetera, right? That's what I mean about... There we go, yeah. There's like a lot of things, but yeah. That's session replay. That's how session replay can help you debug your errors or see any performance issues and yeah, it's like being in the room with the user when the error happens.