Monitoring 101 for React Developers

Rate this content
Bookmark

If finding errors in your frontend project is like searching for a needle in a code haystack, then Sentry error monitoring can be your metal detector. Learn the basics of error monitoring with Sentry. Whether you are running a React, Angular, Vue, or just “vanilla” JavaScript, see how Sentry can help you find the who, what, when and where behind errors in your frontend project. 


Workshop level: Intermediate

107 min
07 Nov, 2023

Comments

Sign in or register to post your comment.
  • Leonardo Faife
    Leonardo Faife
    n/a
    How long will the workshop be? Im in class until 1:15pm
  • Vinita Ramnani
    Vinita Ramnani
    Hewlett Packard Enterprise
    Will this be recorded and shared with the people who signed up for the workshop?

Video Summary and Transcription

Welcome to Workshop Monitoring 101 for React Developers. Learn how to create a Sentry project, handle errors, use collaboration tools, set up alerts, and explore distributed tracing. Set up source maps and wizards to get additional information about errors. Add event context and custom tags to identify users triggering events. Configure custom tags in Sentry to aggregate and filter errors. Explore alerts, issue assignments, and integrations with GitHub. Implement distributed tracing to follow the execution of requests and identify performance bottlenecks. Connect the client-side and back-end using Sentry's trace ID and transaction. Use session replay to debug applications and improve user experience.

Available in Español

1. Introduction to Workshop

Short description:

Welcome to Workshop Monitoring 101 for React Developers. We'll guide you through building a simple app for flashcards using React. Learn how to create a Sentry project, handle errors, use collaboration tools, set up alerts, and explore distributed tracing. Join the Discord for Q&A and enjoy the workshop!

Welcome, everyone. Hey, how's it going? If you haven't already, join the Discord. That's where we will have Q&A. so we've got myself sarah and lazar here who are going we're going to split off so i'll do the first half of the workshop and he'll be in discord and then we'll swap yeah and we will take a short break at the one hour mark and there's a that's to join the um the discord but we have a specific thread for this workshop.

Let's go. Alright. Welcome everyone. Again, this is the Workshop Monitoring 101 for React Developers. I'm Sarah. And I'm Lazar. And we are advocates here at Sentry. I'm normally based out of Washington State, but I'm visiting Toronto today so that we can give this workshop together. We're also going to ViewConf on Friday if anyone else is going. So we'll see you there.

Today what we're going to do is actually give you from start to finish we have a very simple app that we built for flashcards, right? So answering the question, testing your knowledge on things. Shuffling the cards is a really important aspect of learning. And it's built with an XJS. And so we have a very basic app that's built. It's open source. We'll give you the links to all of this, including the links to this deck, which has all the links to everything else. So if you're missing anything, don't worry. And we'll also share them in the Discord during and or after. We're going to walk you through actually creating a Sentry project, seeing those errors get sent, how to use collaboration tools, how to set up proper alerts and then how to do some interesting stuff with things like distributed tracing as i mentioned we'll take a short break at the hour mark but also please feel free to get up and take a break if you need to and then again um when one of us is presenting the other one will be monitoring the chats and discord so if you have any questions feel free to to pop them in there

2. Monitoring Overview and Project Setup

Short description:

Welcome to Workshop Monitoring 101 for React Developers. We'll guide you through building a simple app for flashcards using React. Learn how to create a Sentry project, handle errors, use collaboration tools, set up alerts, and explore distributed tracing. Join the Discord for Q&A and enjoy the workshop!

So here's our agenda. Part one will be me. We're just going to kind of get up and running. I'm going to give you a quick overview of monitoring. I don't want this to be just a lecture. I want this to be more engaging and kind of actually opening up VS code and Century app and everything like that. So just a quick overview. We're going to actually set up a project with Sentry, configure source maps, event context, custom tags. All of these words will make sense eventually, alerts and issue assignments. And then, like I said, Lazar gets kind of the more interesting bit, in my opinion. It's a little bit more fun because he gets to dive into distributed tracing and session replay, which are two of our, I guess, newer features, but also just kind of more in-depth features for applications that might be larger than the splashcard app that we have. Yep. So let's go ahead and get started. I'm going to switch over. Not to this one. Oh, that was this one. I meant to leave this one open and then do this. Perfect. Okay. So, as I mentioned, we've got this flashcard app. If you want to share the link, maybe, in the chats or in the Discord. Very simple, and I've got here my VSCode open. We have it open in here. If you need me to zoom in for anything, let me know. But I'm trying to monitor to make sure that it's all set up properly. Actually, I just realized I totally skipped over the, what is monitoring? I don't think it's like I told you, I don't want to do a long lecture on what is monitoring. OK, but let's do a very quick overview of what is monitoring, because I didn't mean to just totally skip over that. OK, so essentially, as you all probably have experienced, you build an app or you're part of a team that builds an app where there might be a poor user experience. Sometimes this is due to actual like errors within your application. Sometimes this is due to an API call that you made, and maybe the service that you're using on the other side of that API call is having issues. Regardless of why, a user experiences something not great. That user becomes frustrated, and oftentimes developers are too late to resolve the issue when it would maybe make that big of a difference. For example, maybe all of a sudden you just get a bunch of notifications on Twitter that your app's busted. And that's all you get. And there's not a lot of information, but a bunch of people are just saying that it's not working and they're basically leaving, not using it anymore. Monitoring tries to essentially, and this is specifically for sentry monitoring, stop that from happening. so there might be a poor user experience some users may still get to twitter before you log into your sentry alert but sentry detects the issue there's also ways that you can set up some thresholds to make sure that if it just happens once maybe like you just lost one package it's not that like the end of the world but if it happens you know 10 times or 100 times then we want to alert the team. So Sentry detects an issue, and the developers actually get a pointer into the actual problem. So it's not just user feedback apps busted, but instead it is a breadcrumbs. It's a full trace of what was happening. Like I said, Lazar is going to go into distributed tracing, so you can go from front end to back end and to other services. and if you set up things like source maps which we'll go into you can actually get the exact line of code that is likely the trigger of the issue and if you have code owners set up which I'll also go into you can automatically tag the appropriate developer to resolve the issue instead of just having it go through this long triage process where I get this issue and I'm Like, this is not my code. I have no clue how to resolve this. Or maybe it was my code. I originally wrote it, but I'm not the owner of its health long-term. That's someone else. And so the ideal scenario here is that most users never know that there was an issue in the first place. So this is kind of like our tagline. Tagline specifically Century focuses on the developers who are building or monitoring the apps and how we can best support developers in taking action on those broken lines of code crashes and busted API calls. We really do focus on that developer first monitoring solution to give you, like I said, an actionable answer to what the problem is, not just a clue for where the problem could potentially be. Now we will go into the demo. So you can follow this short link for the GitHub repo. We're going to. I already have this cloned on my machine. Exactly. Well, actually, the main branch has Sentry set up, but there is a branch called No Sentry. I'm not necessarily expecting that you all run this on your local machines now. But if you want to do this later at some point, we do have a PlanetScale account and a database with it. You can use a different one if you want. There might be some additional configuration you need to do. We already have a Sentry account. It is just a regular account. It's not like a Sentry employee account. We do that on purpose to give you a more accurate representation of what you would see. And then we did add instructions to the Readme, so you can follow along there at a different time. So I'm going to show you how to set up that React project with Sentry. We're going to configure our source maps, add event context and custom. tags, and then jump into alerts and issue assignments. Now we can actually get started. So like I said, this is the repository and I've already cloned it here.

3. Setting up Sentry Project

Short description:

In this part, we set up a new Sentry project for the Flashcards React Summit US app. We used the Sentry wizard for Next.js and created the project in the Century DevRel team. The wizard automatically added the necessary config files and modified some package files. We also explored the Sentry dashboard for the project. Now that Sentry is set up, we'll proceed to create an error and see how it appears in Sentry.

So like I said, this is the repository and I've already cloned it here. I'm using VS Code. And I, like I said, I'm on the no Sentry branch. And that just means I haven't set up sentry yet. I do have a little sticky note with things to copy and paste make it easier so I don't have to type every little bit in but when you first get started with Sentry we have some absolutely incredible docs in my opinion did I spell that right nope don't I oh there we go and so you can head over to let's say JavaScript and we've got some like install instructions, et cetera. And one thing that I really like is that we have a CLI install for Century and a wizard that makes it just very, very easy and straightforward. So before we run the wizard, what I want to do is actually create a new Century project. So you can see what it's like from the very beginning. So I'm in my Century account. I go to create a project I'm going to choose Next.js in this scenario and scroll down here. You can already do some alert frequencies here, alert on every new issue. We can create alerts on our own later and then again like I said you can also create something where maybe this app is a little flaky and that's okay because it's not a mission critical app. So just like let me know when at these 10 things have happened. Versus this is very urgent. If anything goes wrong, I need to be notified immediately. Then you might want to do this one. We're just going to leave it on alert me on every issue right now because I'm just going to run it locally and so that'll be fine. We're going to name this Flashcards React Summit US, and we're going to keep it in the Century DevRel team. I'll create the project. In addition to having some pretty great Docs, in my opinion, we also just have this in-app experience that allows you to not have to leave the app to go figure out which Doc you should be following. Instead, you can just follow it right here. So, I'm going to go ahead and copy this. It's the same one on my sticky note, which is nice. And you can either use this wizard or you can do it on your own if you wanted to set it up manually. These are all the steps that the wizard will do. And so you can kind of follow along there or, like I said, click on this setup manual and it goes straight to the how to set this up and what config files you need and all of that good stuff. Okay, so let's go ahead and set this up. It's going to open up VS Code again and I'm going to pop into my terminal. Like I said, this is just the regular repository with the no Sentry branch, and I'm going to paste that wizard command in. So we're using npx. It's the Sentry wizard latest for Next.js. It's going to ask me a couple questions. So we are using Sentry SaaS for this. If you didn't know, Sentry also has self-hosted options. Sentry is open source. so you can head over to GitHub.com slash GetSentry slash Sentry and we have an open source repository right here and some really great discussions happening both on I'm not going to deal with that right now both on the main Sentry repository as well as all of our repositories for SDKs we offer SDK support for I don't know every framework Give or take. And constantly adding more. Okay. So, we've got that in there. And we do already have a Sentry account, so I'm going to say yes to that, and it's going to open up the browser so that I can log in with Sentry through the browser. Very typical VS Code type deal. And then we can go to see issues if we want. I'm just going to – that's fine. We can just – we can just be here. I mean, this is not the right project, though, I don't think. So we're going to pop in the right project. There we go. Perfect. So this is our Sentry dashboard for this particular project. And the wizard is setting up all of our config files for us. So we'll actually assign this one to the React Summit project so that we can properly link the project to our code base here. Perfect. So what that did was it added our Sentry CLI RC file. It added some config files down here, you can see. And then it modified some of our other config files in our package. This just our git ignore. It also added in a Sentry sample so that you can send a sample error right away if you didn't have an existing application that you wanted to use. And that was it. that was step one. Sentry's set up now. Sentry is set up now. I couldn't remember if I had a slide for it. I didn't think so. So, we're already done with the first quote-unquote lesson. This is what makes being an advocate here at Sentry pretty hard because you want to get started with Sentry. It's one line of code in your terminal, but we're actually going to show you how to set up some more interesting things here. So, before we get started, I do want to actually make an error and to show you how that shows up in Sentry before we make any other changes. So what I'm going to do is I'm going to run it's actually in this one, yes? No, we're not in Source here. So this is our flash card. Let's actually show you how it works first before I make the error so you can see what it is that we are building and running.

4. Building and Running the App

Short description:

We're going to do a quick build and start the Flashcard app. In the manage section, we'll handle updates and encounter an error when deleting a question. We'll explore the error message and compare it to what Sentry offers. We'll also consider running the app in production mode to see how it differs.

So we're just going to do a quick build. We're going to diff for this step. Oh, diff? Yeah. That's a good idea. This one's a little slow. We need to have hold music. Elevator music while we build. We should make a VS Code extension that anytime you're building a certain Spotify playlist, because there is a Spotify VS Code extension. Oh, cool. So you can like marry these two. That would be fun.

All right, perfect. So that's built, and then we're going to go ahead and start it. And we're going to open that up. So we're running Next.js 13.4, but we're using the pages directory, not necessarily the app directory. So this is what the Flashcard app does. So this is the manage where you're actually creating or modifying or deleting any of your flashcards. You can see that a question is required and answers required and a category is required. So if you try to delete the question and update it, it'll say, no, you can't do that. Please fill that field out. So and then if you want to practice them, they're here. So it'll just show you and then you can see the answer and go on to the next one. We're going to be mostly here in the manage because that's the part that has user input and is more likely to have errors pop up. So the error that we're going to throw in here is not doing a check to see if the question was input on an edit. Seems like something, some kind of issue that I would forget to check for.

So we're in the manage and we're handling an update for this. And if you want to follow along or you're looking at the code in your Visual Studio code or on GitHub, it's on the slug TSX file under flashcards under manage, under pages. And what I'm going to do is I'm just going to comment this one out, save the file. and we're going to go ahead and i can't remember for p is it just this time no just dev instead of build oh yeah got it d v oh div yeah okay maybe i've never done that before then yeah like develop but it's short def d e v dev dev yeah sorry my accent is no no no my brain is I don't think I always just build because I'm way too paranoid about not getting things right, that I always just build and wait the seconds, which is why I definitely made that up. Change the port now. It's on 3001. I just noticed the little message there. I don't know why it does that. Why it did that. Yeah. This Zoom thing. There we go. It's in my way. Thank you. I thought I quit it properly. Yeah, but it's... Who knows? Strange. OK, so now we're in here and what this zoom bar is making me angry. OK, so now what I'm going to do is I'm going to try to delete the question and see if I can update it and we get an error. This is maybe useful, except it's not, because you can see that the issue was where I commented out that line and the handle update. it's telling me fail to update the flash card, doesn't really tell me why it failed to update the flash card. We get kind of like... A faint... Handle update. Okay, so that's useful. I mean, you know, Chrome's getting better. No, you're actually in dev mode. Oh, you're right. I'm in dev mode. That's why. So this wouldn't be happening. See, this is why I do builds. Because this wouldn't be happening if it was running in production. We wouldn't get this nice view here. we might get the cool yeah like interesting bad request okay so let's see what sentry actually offers us instead so we're going to go ahead and refresh this and we can see that there was one release and I think we need to come right down here and we'll see the error that we got so we can click into this error right here. We can see that it failed to update, flash card, reason bad request. Same as we got as that top-level error in dev mode. A couple of things to point out before we jump into what the issue was and the information that you would get right here at the top. We've got some interesting thing. We don't know which user this was, But we do know that this was Chrome, which version and which version of Mac I am running. We get some additional information like this was in development mode. So I think I'm going to run it not in development mode. We should definitely try it in build mode. Exactly. We actually see which URL.

5. Configuring Source Maps and Wizards

Short description:

We can set up source maps to get additional information about errors. The Sentry dashboard provides breadcrumbs and experimental AI solutions. We can view issues for specific projects, across multiple projects, and in different environments. Sentry helps monitor errors and performance in production, capturing metrics from users worldwide. We want to measure performance on users' machines, not just our laptops. Let's create a new error and see how it appears in development and production modes. Source maps allow us to find the exact line of code causing the issue and connect it to our repository. We can run the source maps wizard, which also sets up the Next.js wizard if desired.

So it's for the, what is a component flashcard, which was the one that we were, we were trying to update. So that's useful information and context. And the file was actually the one that we added later in our checklist.

We can come down here and we can get this beautiful little callout stack trace, but it's still not super useful. It would be nicer to have additional information. So we'll set up source maps here in a second, but we can open up a replay. I'm not going to give you a sneak peek to that because Lazada is going to do that later. And then we get these breadcrumbs, which actually sends us through the entire event that happened this error. So we can see in here just kind of all this additional information, follow through. Just lots of stuff. We do have some experimental things like AI solutions. Notice kind of our humor. Maybe you'll get lucky. Maybe not. We can check out what that solution, suggestion is. I'm not going to do that right now. And then we have all this additional information down here which I will walk you through kind of some of the interesting things happening there.

On our issues tab, we can see for a particular project. We can also look at issues across multiple projects. So if you have multiple projects for the same application, maybe you have them written for mobile versus something else. We can also see for all environments, development or production. And then we can also change the time range. So if you're looking for something that happened in a particular time range, and there are other issues happening, you can kind of qualify that. So those are some of the basics. But this is just like sweeping. This is for DevMode, right? So we're basically looking at the same information, or maybe even more, that we can actually look in Chrome. The idea that Sentry likes to solve is that we are going to be using this to monitor for errors and performance in production. So in production means that we're going to capture the errors and the performance metrics for a lot of the users of our app throughout this whole world. So not just our laptop. For example, if we test it out on our laptop, I mean, we got MacBooks, M2s, etc., yada, yada, yada. Not everyone's going to have that address in use. There's the port 3000. But I thought I killed it. We need to manually kill it now. But yeah, the point is that we want to measure the performance on production. because it's going to work fine and it's going to be performant on our laptop but not necessarily on our users laptops or desktop machines or etc yeah that's pseudo LS Office it's a good one 91283 yeah okay there we go See your fancy dev tricks. Let's check out. Let's create a new error and see what we have. We're gonna go into what is a hook. Yeah and check it out. We don't get the dev pop-up because we're not- Infinite spin yeah. Exactly and then we're gonna go ahead and show the developer tools here and see that it's even less helpful. Yeah. Bad request. It's not giving us. Yeah. It's not the actual file. Exactly. And then if we open it up over here now, by the way, if we're in development mode, we only have that one. And if we're in production mode, we only have that one. So this is our air in production mode. And we can see already. Did we do it? Oh, Did we already set up source maps? No, but this is like a – It did have like a – So we've got a suspect commit here already, so it's suspected that this commit here was likely the one to have caused the issue. By that specific person right there. And we can actually come down here now and in our – We can see here the transaction happened on the manage flashcard slug TSX file. And so since Lazar was the last person to touch that one, it was likely him causing the issue. Perfect. Okay. Now we're going to jump into configuring source maps. So the benefit of configuring source maps, you're going to actually see this here in a moment. But basically, it allows us to find the exact line of code that is likely causing the issue and connect it up to your to your repository. So what we're going to do is we're going to run the source maps wizard. Now, one thing that's interesting about the source maps wizard is that it will also run the Next.js setup wizard if you want to. Can we hold on a second? Yes. I think we actually have the source maps automatically. Yeah, I think it might have. Hold on. Let me restart the project. because I think Sentry outsmarts us. I can see a few bundles.

6. Setting up Source Maps and Wizards

Short description:

We're going to run the source maps wizard to set up source maps for our Next.js project in Sentry. We'll delete the RC file that was causing issues and authenticate again. After building and rerunning the app, we'll see that errors will now provide additional information with the stack trace. There were two questions about errors bubbling up from libraries and filtering errors in Sentry, which will be addressed shortly.

I know. I think what happened was, so if we go into the projects, so Sentry ships often. We are, like I said, open source. And so you can see all of the times that we're shipping. We're shipping often. I love working for an open source company for that reason. But some of the things about that is that new things happen, which make it better for developers. So instead of having to set up your Next.js project with Sentry and then add source maps which seems kind of silly to do for both of them if you set up a Next.js project in Sentry typically it will have source maps set up already so we didn't actually have an artifact bundle but we do have one for the release bundle so there is some no I actually deleted I actually deleted all the artifacts let's try to trigger an error now so we're not following along we had source maps, which was giving us some additional information. Yeah, and also deleted the the issues as well. So, we're basically... Yeah, we're basically starting from scratch. Whew. What do I keep doing? There it is. We didn't ask the demo gods. We didn't. We just did our normal routine. Yes. We usually address to the- OK. Perfect. So, now we're going to come back in here, we're going to go into our React Summit US, We can see it's still loading up the issue. There it is, our unhandled issue. And this is the not as interesting information. We don't have anything. This is the same information that we're getting over here. It's not useful, right? And so without source maps, that's what you get. We do still get like this happened potentially because this is where it's touching for the transaction. but we don't get the actionable trace or... Yeah, stack trace. Stack trace, yeah. We don't get the actual stack trace with the line-in code there. So now we're going to go ahead and run this source maps wizard. And I think I just realized what I was doing wrong. We didn't delete the RC file. The RC file was the reason why our source maps was automatically being uploaded. Okay. It's going to authenticate for us again. There we go. So yeah, if you were to install the Sentry SDK manually in a Next.js application, you would do this. Yeah. Exactly. And then this one offers to start the Sentry Wizard for Next.js, which is the one we did right at the beginning. We don't need to do that again because we've already done it. So I'm going to say no. is for if we wanted to do it manually. But we do already have all of this in our Next.js config file which should be right here. So, you can see all of this does already exist down here. So, we don't need to do that. So, yes, we've done it. We're not using a CI CD tool, so I'm going to say no, and we're done. So, now I'm going to build, and then I'm going to rerun. And then we'll see that this error where we don't have a lot of information we will get additional information with that. Have there been any questions? We have just two questions. Is it common for error to bubble up from libraries and is there a way to filter certain errors within Sentry if so how? Yes we actually do filtering with some custom things in just a moment so yes and then bubbling up is kind of like distributed tracing. We'll talk about both of those. There's also a property within the century.init method that lives in the century.client .config.js file or the server or the edge, whatever it is. So that one is going to allow you to filter out any errors that could happen based on a certain rule. I'll try to find a link In the docs and I'll share it in the chat. I was trying to go in here so we can see some source Maps. So, now, we can see these bundles got created. There we go. Okay. Perfect. So, now we're going to rerun. Building is what sends up the source Maps, so, now we're going to rerun. I'm going to go into what is a promise. I'm going to delete this one, update. We get these same not super useful errors in our developer tools over here on the side. But then inside of our actual project. We should get a new error right here and then this is why the first time we showed it we had the suspect commit because source maps were already set up. We have additional information here and then now we actually have the stack trace.

7. Adding Event Context and Custom Tags

Short description:

We're adding event context to the Sentry event to identify the user triggering the event. This is useful for providing immediate help to major clients. We're adding the user's email as the Sentry user ID. The code is added before the await code. We're importing Sentry from '@sentry/next.js'. Note that this involves collecting PII, but Sentry automatically scrubs all PII data to ensure privacy and compliance.

And we can see this right here, going straight into that. And then we can even open the line in GitHub. There it is. That was the one that actually sent the error. Okay, so that's the difference between source maps and not having source maps. The not having source maps, we don't get that stack trace and we don't get that click into GitHub repo, and we don't get that suspect commit with the assumed culprit of introducing the error.

This also automatically assigned, or not automatically, but suggested to assign Lazada to the issue, but we'll show how to do some custom alerts and issue assignments. This is basically only for the suspect commits? Correct. Based on the commit data.

So now we're actually going to add some event context which will allow us to search through issues in more interesting ways. Like I said, we can already search through issues for development environments in a certain kind of timeframe, but it would be nice to know what kinds of things that we can search through here as well. So we're going to create a Add Some Event context and set up some custom tags so that we can do that search here. All right, so I'm going to lower my terminal I'm actually going to jump into some code here, we're going to leave that error there. We're going to go into the same file, but we're going to add the data for the current session that is happening right here. And I'm going to bring in use session. Perfect. And then down here, when we are actually trying to update with the question, the answers, and the category, we're going to add in information of if there is data from the session and that data has a user with an email. we're going to set the century user. So the user ID in century to that email address. So then that way we know which user actually had this issue. This could be really useful if you have like major clients where if they run into a particular issue, you want someone to immediately reach out to that customer and offer like immediate help or one-on-one help. So that's what we're going to do. This happens before the await code, right? So we want to do that here. Sorry I was answering questions from Discord and wasn't following. Gonna add in century here. Import Sentry... What was it again? Everything is Sentry from... No, yeah. It was import everything from... Yes. Sentry from... At Sentry slash Next.js. Thank you. we're missing the quotes. Yep. Okay. So now it's filling in there, and we're gonna do email is set to data.user.email. So, that's adding some additional context to the Sentry event, essentially. To say that the user that's triggering this event is this user. Okay. going to build and run that and show what that looks like in Sentry. Note that this is PII and if for example your project should not collect PII or there's a rule that you cannot get any personal information outside of your database to a service like Sentry, you would be breaking that rule in this case. But by default, Sentry scrubs all the PII data automatically. So you don't need to worry about leaking any user information and breaking a law. If you're interested in that, I can send you a link for our privacy in PII if you want to learn more.

8. Setting up Contexts and Custom Tags

Short description:

We're particularly critical around PII and the session replay section demonstrates its complexity. When triggering an error, we now have additional context to understand why it occurred. The same error can have multiple events with different users, but without additional context, we can't determine if it's the same user. Setting up contexts is simple, but custom tags allow for alerting specific people or areas of your app for critical issues.

Yeah. We're particularly critical around PII, especially because of... You'll see in this... In the session replay section how tricky that can get. So, you can see here, I'm logged in with an admin at admin user, which is just kind of a default one that we have. So, I'm going to go ahead and trigger that error again. And this time when we come in to our issues for this project, not only will we get that same error showing up but this time will actually have additional information or context to why that error showed up. Takes just like a second. Usually you're not doing it right away. You can see here that now the same error because we have updated source maps when we triggered this error has two events with two different users. It was the same user that triggered that event. However, because we didn't have the additional event context of the user's e-mail address, we can't tell for sure that it was within Sentry that it was the same user. So technically from Sentry's perspective, we only know that it was two different ones. You can actually see that this one happened seven minutes ago, but if we scroll over to the other one, we can see that this is the one that just happened a minute ago. The difference here is over here, we're not sure who the user was. we had no context into who this user was. We did have context into what kind of devices and browsers they were using but not the user. Here we actually have context into that user. Then everything else is pretty much the same. We also down here though in the headers see that this email got added to there as well. So that's basically how you set up contexts. It's fairly simple. It shouldn't be too hard. Again, it's kind of difficult being an advocate here because it's just a couple of lines of code. But I do want to show you setting up custom tags because it might be that there is a particular type of operation or a type or like area within your app where issues might be more critical and you want to kind of alert people sooner or certain people or things like that.

9. Setting up Custom Tags in Sentry

Short description:

Learn how to set up custom tags in Sentry to aggregate and filter errors based on specific operations. Tags are key-value pairs that can be added to Sentry events. It's recommended to use primitive types as values for easy searching. The Query Builder in Sentry allows you to search and filter errors based on tags, providing flexibility in error analysis. Check out the Query Builder documentation for more details on constructing queries.

So I'm going to show you how to set up a custom tag now. We're going to add this line of code to our handle update, which is on 125. So within the same thing, we do it right here is what we wanted to do. So we're going to say that if we're in the handle update function, then we want to add a tag to Sentry. And this tag is what operation we are doing right now. And in this case, we're trying to update. We can also add the same tag over to the remove. So I think we can just kind of I mean pretty much anywhere, right? So and we'll just do remove here. Yeah, it's just the tag. Yep So if an error happens on the handle remove instead then that operation tag will be for remove if it happens on the update it'll be for out. Exactly and the beauty with the tags is that you can actually aggregate and filter errors based on them. So like the contexts you can add additional data to the error itself, but with the tags you can actually search and filter errors based on the tags. And you have the whole creativity to add any custom tags which usually should be just a key value, like primitive types instead of objects, etc., because of course, you'll be searching. They're meant to be searched later on. So we could even do something like this. where we are causing another error for if the answer is empty when you're creating, and we're setting the tag to operation is create, and then we just need to make sure that we're adding in sentry here. Quick question. Yeah. Related to the setup of the set tag. so Lazar said it's a key value pair and I'm just trying to better understand the it didn't look like it was being inserted as a as an object in a key value pair but I'm guessing it it gets interpreted that way and so the first value operation. Yeah that is the key com of value basically the two arguments are the key and the value. I wanted to say that for example for the value instead of create or remove or update if you wanted to put an object there and I don't think you won't be using tags correctly basically. Yeah. Yeah, because you would have to search for that object specifically and it's better to just throw a string and just label that error with something that you can use later on to identify the error. And so when searching for this tag in Sentry, you would search Remove, that would be the key? Yeah, it will be tag, transaction.tags, and then remove. Yeah, I'm going to send you a guide on how to search for this. OK, could you also search then, I guess, the key itself, operations? Yeah, I think so. Let me see. Because searching in Sentry is done by a custom, like a it's basically you're building a query. It's not just like a fuzzy search. Here's a guide in Zoom and I can also post it in Discord as well. on the actual query builder and how you can use all the transaction details like context and actually tags etc and the type of the transaction to search for certain errors and filter out anything that you want to filter out basically so yeah using the query builder and the query builder syntax you can achieve that using the tags using the tags, because you might have multiple ways to create, for example, in this case, a flashcard, so that specific error can come from two or three different sites. Having that tag with the same tag, like Operation Create, can help you aggregate all of the, basically, aggregate all of the errors, even though they're not the same one. So you can actually see here, we have two or one new error and then one new kind of event within that type of error. So the new one was for the operation creates. So here is that custom tag right there, you just like click on it and it'll take you to search operation colon creates. Yeah, we can change this one to update. And then this is the other one, which is one of three events for this particular type of error. This one has Operation Update here as one of our tags. And if we scroll up, again, because we didn't have the custom tags before, we're not gonna have Operation Update on the one with the user email, nor are we gonna have it with the one with out the user email. And yeah, this is how you would do the searching. So we can even see like just for when there was, this one's for both. I think isn't there a way of doing or? Yeah, I think. Just or. Just or, but like outside of it. Yeah. Anyways. Yeah. Check out the Query Builder docs and you'll see like all of the ways how you can logically include or not include, yeah, or it's like capital or without, yeah, explain it in English.

10. Alerts, Issue Assignments, and Integrations

Short description:

Check out the Query Builder docs for logical inclusion/exclusion, capitalization, and other options. We'll cover alerts and issue assignments, integrations with GitHub, and various triaging and chat platform options. We'll explore ownership rules and code owners files, mapping GitHub profiles to Sentry profiles, and configuring associations.

Check out the Query Builder docs and you'll see like all of the ways how you can logically include or not include, yeah, or it's like capital or without, yeah, explain it in English. Cool.

Next, what I want to show you is and then we're gonna take a short break, this one's gonna be super quick, we're gonna do some alerts and issue assignments. So you can see that with suspect commits when you have the source maps set up you can, or it offers some commit data here, but it would be nice to have alerts set up based off of the logic of your org or of your company or your team. So we're going to talk about that first.

So what we're going to do is we're going to jump into I want to show you some of our integration stuff. So we have the GitHub integration installed here that gets installed when you're doing source maps. And that way it can actually connect over to GitHub. We also have, you know, all of these other integrations here. Some of these are related to deploying your app or continuous deployment or things like that. But some of these are related to your team's triaging process like PagerDuty, Jira or to your team's chat platform. So we've got Microsoft Teams, we've got Discord, we've got Slack. So if we wanted to, we could set up Slack. So then that way an alert can happen via Slack and, you know, he can be DMed the second that something happens on one of his commits. We're just going to use email for this one. But I just wanted to kind of give you an overview of the ridiculous amount of integrations that we have. And you can even search by particular categories here for what might be more useful for you and your team.

So we're going to go into the project settings for this project, and we're going to go into ownership rules, and we can do a couple of different things here. So one is we can actually just kind of create rules within Sentry. Here's some examples. we also have a link over to the docs again for all the different types of things that you can match to automatically alert particular people or rather to apply ownership to certain events for particular people. So you can do it based on the path, module, URL, tag, which can also be custom tags. And then we have some additional information here. Additionally, you can have if you already have a code owners file you can do that instead. So, for example, if we wanted to create a code owners file let's try it that way. So I'm just gonna pop out into here and I'm gonna create a new folder to the GitHub folder and in here I'm to create a new file that's just code owners. This is not Sentry specific, this is just code owner's file. So I'm going to say if it's related to flashcards then we should tag Lazard and if it's related to categories, we should tag me. These are our GitHub user So you can see this is my GitHub profile that pops up when I hover over it. And this one is his, maybe, like pop ups. There we go. I don't know if you're as well. There it goes. So this is not related to our Sentry ones, this is instead related to our GitHub ones. So I'm going to go ahead and build this again. and when it's done building I'm going to import code owners on Sentry after we do that we can actually map someone's github profile to their Sentry profile to make sure that if we have a suspected commit on github by this particular github user that we know who within the sentry system to tap to alert and in what ways? So we're going to add an existing code owner's file from this repository. We can preview the file here. There it is. And we're going to add it there. Oh, it's already in use. Darn it. Let me check. I think it's because, well, I'll just paste it in here as well. It's because we're using the same repo on multiple projects. So, actually, this requires the century users. How do we do it when it's not? Can you remove it from the other projects? Yeah. We can try that. I might be able to. We should have done that ahead of time. Actually, I'm going to delete the integration and create it again. Or actually, yeah, you have the rules. No, but this is React Advanced London. For the London, yeah. I think that's why, though, is that it's delete. Here we go. That one was already in use. typically you're not going to have multiple projects on the same repository so there we go that's how it should have happened so you just click on import it loads it in based on your source maps. It'll identify the GitHub code owners file and it'll bring it in for you and you'll see here the owners and who they are. Then on the general settings, we want to have, sorry, not for this project for all of our organization. We want to make sure that we've got our, where did our members? No. Moving for the user mappings. Yeah, integrations. Thank you. But for the project, huh? No, it's in the integrations configuration. So then under the GitHub integration, because GitHub is what we're using for code owners, we can go into configurations and we can configure a particular person with a Sentry person. So we can make sure that this person is associated appropriately with that Sentry user and this person is associated appropriately with this Sentry user. So these are the ones that we're going to use. We can add additional ones. So if we wanted to add, I think this is Salma's, then we can come in here and manually add her. You can manually add her GitHub project to this as well.

11. GitHub Integration and User Assignments

Short description:

When setting up the GitHub integration in Sentry, it automatically pulls external users from the codeowner's file. This allows for automatic issue assignments across the entire organization. The configuration is not specific to individual projects but applies to the entire organization. Multiple configurations can be set up for different repositories. Code mappings and user mappings can be defined, and team mappings are also possible.

The idea is that you will never do this because as soon as you create the GitHub integration, it's going to pull all of the external users that could potentially be defined in a codeowner's file. And that's, for example, if you go back to the user mappings now, you'll see that little GitHub icon left of the name. That indicates that this user has been automatically pulled from the actual codeowner's file. So tell Tell me who is Dr. Guftles within the context of Sentry accounts. So, that way we can actually have the automatic issue assignments, etc. And this isn't done per project. This is done for your entire organization. So, you can see here that for the GitHub integration for the entire organization, we have these configurations. You could have multiple because this is just one repository that we have connected to our Sentry accounts. So we can have multiple here and then we're going to bring that in. And that's where the configuration happens. You can see that this is coming from this repository. There might be some code mappings as well. This is because we did actually bring in code owners to that project. And then here is the user mappings. And then there could be team mappings as well. but we don't have that for this one. It's going to be exactly the same as user mappings. Exactly.

12. Tagging, Alerts, and Observing Errors

Short description:

We comment out a line of code to ensure the correct tagging. Triggering the same issue and deleting a question to observe the same issue. Exploring the assignment of issues and creating custom alerts based on specific conditions. Setting up actions for critical and warning statuses, and assigning owners to alerts. Testing the alerts by triggering multiple errors and observing the graph.

Okay, perfect. So now what we're going to do is I'm going to comment out a line of code that we'll want to basically make sure that he's going to get tagged instead of me. So inside of our flashcards, we're going to, what was it the online? 123, was it, or something like that? 13? No, that's the API. Pages, manage, flashcard, slug. We said 123? Something like that. Yeah, along those lines. Let's jot down 116. Thank you. Oh, commented out. Oh, yeah. Still same error. I don't know why I said commented out again.

Okay, so we're gonna trigger another one. Same issue. This time I'm gonna delete this question here, update, same issues over there. We're going to jump back into our project so that we can go see that issue. This one is a little old so we're going to refresh again. 18 seconds ago, so we're going to pull this one open. We've got the suspect commit. we're going to go to the most recent event, which is right now, and we should have someone assigned right here, assigned to him. And we can see that at the very top. Sorry, if we go to the previous event where we didn't have this, well, I guess now we've assigned it. So he's been assigned to this whole error, but for other ones you wouldn't have found that. Here you can see this one he's colored in, like colourful, because it was actually assigned. This one is a suggestion.

Quickly we're going to go over alerts. So now what we're going to do is we're going to head back into alerts over here, and we've you've got send a notification for new issues, but I'm going to create a new custom alert. It's going to be based off of issues, but I only want to do it in our React Summit for production environment. I don't care if an issue happens in development, that's going to be normal. I'm going to say when an issue is created and you can add additional filters here. So you can have tags, You can have certain attributes, categories, just like basically anything that you might want to have some kind of filter for, and then you would perform a particular action here. So these are some of the conditions that would happen. We can set up Slack, like I said, and I'm going to set up an interval for every five minutes. This one's just a regular alert rule. Should we set up a custom alert instead? I would do like a number of errors. Yeah. Instead of just an issue happening. Good point. OK. So number of errors in a one minute interval on this particular one for only production event type of error. And I'm going to say that if there are five errors being sent. So the difference, you know, an issue is something that may have a lot of different transactions within it. So I'm saying every time one of those error transactions happens. So if it happens five times. In a single minute. In a single minute. Then it's critical. If it happens three times in a single minute, then we're just going to get a warning. I'm going to create an action for critical status that's going to email the entire team, and it's going to email everyone on the Sentry DevRel team. We can also set up an action for a warning status that'll just email Plaza. and then we would establish us as the owner, enter the something is busted. Obviously not a good role name, but just for the purposes of this demonstration. Perfect. So we've got this in here. We've got that issue is ready. Sorry, that alert is ready to be alerting. Yeah. So let's go ahead and give it a try. We need to trigger a lot of errors now. Yeah. Okay. And by the way, when you get an auto-assigned issue to you, you actually get an email from Sentry saying this issue has been assigned to you. So I can go ahead and check it out immediately. Okay, I think that was a lot. Yeah, we should see the graph. There we go. You see that little line over there? Yeah, this is for the last seven days. You can change the date range at the top to be like the last five minutes. you can also type it in last five minutes that works as well Will it work okay, it's not gonna work in this case it's gonna work in the issues case Yeah, because I think this is yeah alerts have a different one. But you can see that line over there It's below the red light, which is the critical threshold.

13. Distributed Tracing and Session Replay

Short description:

We shouldn't be getting emails now. We'll take a 10-minute break and come back to share the email that shows the alert worked. Then, we'll do a demo on distributed tracing and session replay. In the last hour, we set up our react project with Sentry using the wizard. We connected source maps, added event context and custom tags, and set up alerts and issue assignments. Next, we'll continue with distributed tracing and session replay.

We shouldn't be getting emails now. Yeah See here. We've got one that's above the red line over here in the we've got seven Yeah. So we should have definitely gotten an, oh my gosh, something bad is happening. Yeah. We had 10. We had 10 happen. So we should be getting emails. I think it would actually go to my personal email, which I'm not going to open on screen. So I will verify that in just a second. When we come back, I will have that one open. but we want to take a maybe even like 10 10 a minute break well let's say let's say we'll come back at 15 yeah after the hour nine minute break so a nine minute break um we'll still be in discord i'm going to stop sharing my screen for a moment so that i can just open up discord we can chat with you all um share some additional things and then we will share that uh email to show you that the alert worked.

And then the last thing that we're going to do is do a demo on distributed tracing and session replay. And then we'll be done. So let's come back at 15 past the hour. What's nice about waiting for that minute or so is that we've got the initial email where something is busted. That was what we named our alert, by the way. So if you named it something more interesting, it'd be better. We can see kind of the, you know, we can download the graph. We can see it right here in the email. We can click over into the alert itself and dive into why. So number of alerts was above five in one minute. That's why it was triggered. We can see which ones, like which issues were related to that and then notice that it says it alert status is resolved here and that's because um a minute has a minute passed and we didn't have any any so the likelihood is that it's no longer an issue but we received both emails the one where something bad happened as well as the one where they're like you know what i think it's probably fine um it was just a Yeah. But because you get both emails or it gets triggered in kind of whichever way you prefer email slack, teams, etc. You can follow up still. You can also meet this alert. This kind of opens it back up over into century and it'll automatically mute the alert. but then allow you to kind of be in here and unmute it if needed. You can also mute for yourself, mute for everyone, edit the rule, duplicate it if you have a fairly complex rule that then you need to do the same thing over and over again. So lots of different opportunities for alerts here. That mute for everyone, that can be a cool April Fool's joke. Oh, gosh. Yeah, like, hey, it's nothing. There's no issues with our app, April Fool's. There's a lot of issues. That would be such a morbid. Yeah. So this is what the emails look like. And just to kind of wrap up, what we did in the last hour was use the wizard to set up our react project with century. We created a new project on century. We used the wizard to do that, to connect it up. We use the wizard to connect source maps. We added event context. That was the user's email address. We added custom tags. That was which operation the user was trying to perform. We set up alerts and issue assignments where we assigned anything regarding flashcards to him and anything regarding categories to me. And then we set up alerts so that if we had any number of event like errors, number of transactions of those errors happening, three or more, it would be a warning, five or more, it would be an error, like a critical error, and we would get an email all happening in one minute. So that's what we've done so far. And next, what we're going to do is continue with this same app. So you're not going to have to go through all that setup again, but we're going to do some slightly more, in my opinion, interesting monitoring things with distributed tracing and session replay.

So I'll pass it off to you sir.

Okay, this can work. So we are going to start with distributed tracing. So, distributed tracing is a really cool debugging technique that exists for a reason. Let's do a quick history, so we can see why distributed tracing exists. Like back in the 90s, when we had single concurrency. We're talking about Apache's HTTP server. When a request came into the server, the server was just handling that request into its own child process. So if we wanted to see what happens to that request, we will just pull the logs from the child process and we were happy. That worked for the time. Then we had a bit more advanced frameworks, like for example ASP.NET in AIS, where instead of just handling everything in a single child process, it didn't fork a child process, but it handled that specific request in a single thread. So in order to figure out what happened in that specific request, we couldn't just pull the logs from the actual child process. We needed to label them based on the thread name. So when we pull the logs we just filtered out all of the logs that are for these threads and there we go we can see everything that happened from our console.log. And that kind of worked then we had the new wave of frameworks which were still advanced concurrency and we're talking about frameworks like Node.js, the event loop based, the asynchronous promises, features based frameworks, right. So what Node.js does is when a request comes in, it's not going to just handle it in a single thread, multiple threads are going to handle that request so in order to read the logs we can't just filter out on one thread because our logs are basically everywhere now. So, what we did and what we needed to do is figure out how to label the log messages with something unique to that request. And remember this, because this is going to be important.

14. Implementing Distributed Tracing

Short description:

We generated an ID for every incoming request and prefixed all logs with it. However, with the introduction of Docker and AWS, our backend became distributed, making it difficult to read logs across microservices. This led us to explore distributed tracing, which allows us to follow the execution of requests, jump between microservices, and see the whole picture. Distributed tracing provides a trace view for transactions, with spans representing different operations. By expanding on spans, we can see what happens on the backend during the request execution. This helps identify performance bottlenecks, such as a database write that takes longer than expected. To implement distributed tracing, we obtain the current scope and create a custom transaction. We then start child spans for different operations, such as marking a point in time or executing a function.

We generated like an ID for every incoming request and we prefixed all of our logs with With that request, we can get the logs, filter out based on that specific unique ID, and we can still see what's going on. And then what happens? In about 2010, Docker and AWS come in, and they make room for containerized apps. And guess what? Our backend might not even live on the same hardware anymore. So our logs are extremely distributed and we can just go microservice to microservice to read the logs, right? It doesn't make sense. That's the point where we were like, okay, we need a better tool for debugging, a better tool for us to follow the execution of the requests, jump between the microservices as it does and see the whole picture at the end. And that's basically distributed tracing. So, right here I have a view and that is a trace view for one transaction. As you can read from the top, it's updating flashcards. Okay? And if you scroll down, we're going to see the span waterfall. There's a mark span, which is a span that doesn't have any length. it says making the API request. So this is just like a little flag. Then we do the HTTP client which executes a put request to the API slash flashcards slash the slug, which takes like 1.1 seconds as we can see. There's a cache span mutating is double your cache that took about 200 milliseconds there we go there's the actual cache mutating and at the end we have a serializing response so this is pretty much what we can also do in console log because this is what the browser gives us right but the cool thing about distributed tracing is that we can actually expand on certain spans so we started the transaction or we started the trace on the client side but then we sent that unique identifier which is called a trace ID. We send that off to the API handler in our Next.js app and the actual server continued that trace. And if we click on the plus here that's on the actual HTTP request and expand on it we're going to see what happened on the back end while this request was executed. So first, db.sql.prismaspam happened, user find unique. That means we try to find the user that's making these requests. Then we try to find the category. Then we perform some category checks. And I'm going to go into the code and show you this whole thing. I just wanted to set the scene by showing you this portion so you know what tracing is, and then we can dive in. But yeah, category checks, then another Prisma span that tried to find a specific flashcard. Then we did some flashcard checks as well, which is just a function. And then in the end, we have another Prisma span, which is flash card update, and that takes 756 milliseconds. If, for example, you deem that this request takes a lot longer than you would expect, with distributed tracing, you can clearly see where most of the time goes, and you can see any performance bottlenecks that you might have in your application. So, for example, in this case, we're talking about a database write that takes 756 milliseconds as opposed to the reads, which are like 150 and 80 milliseconds. Is that too long or is that normal? That's up to you to decide. It all depends on the technology that you're using. If it's like a serverless database or it's right there in the same network close to your VPS, et cetera. But yeah, that's for you to decide, but you'll have an overview of all of the functions and operations that happen along that requests. And the spans, as you can see, they're pretty much trying to mirror the structure of our code, right? So we're making a couple of Prisma queries here. We have a function to check the legitimacy of the category. then we make another query, then we create another function to check the legitimacy of the flashcards that was retrieved. And at the end we updated everything when the checks actually got performed successfully. So let's see how we can achieve this. And by the way, yeah, as I mentioned, this is the updating flashcards. So going to this screen and hitting the update button, that's when the trace happens. It goes on to the backend, it instruments the Prisma queries, and then goes back to the client side to perform the rest of the stuff, which are, of course, mutating the cache, this is the mutating of the cache, and then, again, serializing the response. All right, so, that's distributed tracing. Let's see how it actually is implemented. So, I'm going to jump into the source slash hook slash flashcards file and yeah this is just a file where I keep all my hooks. If we go to line 87 we're going to see the update method. So then this is the exact method that we're importing into our page and we're setting the on click button to execute at this. So, first we can see we obtain the current scope. And it's like century.getCurrentHub.get scope. What is a hub? What is a scope? The hub is basically the central place where the SDK keeps everything that it needs to send, like all of the transaction data that it needs to send to the actual Sentry instance. Whether that's the SAS, the Sentry.io, or your own self-deployed Sentry instance. So that is the hub. It knows how to receive data and how to send the data so you can view it later. And a hub gets created every time you call Sentry.init. And if you notice that, for example, if you go to Sentry.client.config, this is how we initialize Sentry into our app Sentry.init we pass the DSN which points to what is our project and our deployment etc so this is how it knows where your Sentry account lives right when this thing happens when the Sentry.init method gets executed a hub gets created for us and then on top of the hub immediately a scope gets created to it and the scope Scope is actually more user-facing, so you won't be able, not be able, but you won't necessarily be interfacing with the hub. You're not going to care about the hub, but you might be interfacing with the scope because the scope keeps all the extra data that we want to send along with the transaction. For example in the first part, Sarah added tags, added some additional context to the All those things are being kept into the scope. So when we want to send a transaction to our Sentry account, the scope gets popped from the current hub and it is being sent along with all the information that it keeps. And then we create the scope again with a clean slate, right. So in order to do this we need to obtain the current scope. scope so we can get the current hub and get the current scope because we want to add information into it that's the first line and then we create a custom transaction called updating flashcards before i proceed i just want to tell you that you don't necessarily need to do this because the century sdk is going to do it automatically for you i wanted to make this super obvious. So you'll see how it even works under the hood. And if you want to manually instrument parts of your code that is not automatically instrumented by Sentry, by the SDK, this is how you would do it. So here's how we create a transaction. Sentry.starTransaction and to make that the actual transaction that's going to be sent with our request, we get the scope and we set the root span to be that transaction. Beautiful. So everything we do is going to be included into our trace when we send it. Cool. And then we can see the first mark span. Transaction.StartChild will start a child span on that transaction. The operation is mark, and these operations are actually... the operation names are actual names and I'm going to send you this document there we go so you can see which of the operations operation names are supported here's the mark it's just a point in time a little flag it has no duration and here's a function which is just a general function right there is also Also like a page load event, navigation, resource, UI, et cetera, et cetera. And even some framework specific like Svelte, Angular, Vue, React events, et cetera.

15. Connecting Client and Back-end with Sentry

Short description:

Learn how to connect the client-side and back-end using Sentry's trace ID and transaction. The Next.js SDK automatically handles this process, but you can manually connect services in other projects. Prisma queries are automatically instrumented with Sentry's integration. The category checks span verifies the existence and ownership of a category. The flash get-flash part retrieves flashcards and performs checks before updating. The response is closed without calling the finish method.

So that was, let's go back to kitty. There we go. This is how we make that little flag, that mark span. And we noticed that there is a finish method at the end. That means wrap everything up and append it to the actual transaction so it can be sent at the end. If we don't call the finish method, it won't appear into our trace. Okay, so that's how we created the first one.

Then we obtained the headers. And then we append the SentryTrace to the Sentry-TraceHeather. trace ID, that's the unique ID that I mentioned before, that we want to append or create for every request, so we can trace the execution of it, even though it's on the backend or even though it spans across 10 different microservices. The transaction has its own toTraceParents method that returns a string, and if we send this Sentry-trace header, the backend or the microservice that we're going to hit or whatever receives our requests, we'll know how to continue the trace from this point on, right? Because we are still in the hook. We're still in the browser. When we send off the request, here's what we started so the backend can be like, okay, I know, I see a trace. I'm just going to continue contributing spans to this trace and then I'm gonna get it back, or, like, send it off to even a different microservice. So this is how we connect the client side and the back end, right? The front end and the back end. Again, this is not something that you need to do. The Next.js SDK will just do this for you. But, for example, if you had a different project that might not have this built automatically into the same tree SDK, this is how you would do it. The actual trace parent returns the trace ID dash the last span ID dash a value, which is like zero or one to indicate whether the transaction is sampled or not. But that's basically it. It's just a string. So as long as we're able technically to transfer the string, we can continue the trace across all of the backend services even Chrome jobs like we can actually save this to a database retrieve it I don't know in a Chrome job at midnight grab this entry trace and append it to the basically append it to on the transaction so we can continue the trace that happened maybe a few days ago we can still contribute to it right so this is how we connect these services to contribute and to to contribute to the same trace cool so this happens and then we just create a little fetch method with our headers uh sets um that we created previously and this basically is the instance of, uh, automatically, like the Sentry SDK being able to automatically instrument it. And that's this span right here, the HTTP.client, cause we created the mark span, but we didn't create the HTTP client. And that's been done automatically by the Sentry SDK, because we can see see that a network event happens and the SDK itself is going to create that span for you. So that's why I mentioned you don't need to worry about this. But okay cool. We are sending this off and then we're continuing on the backend. And I can open the backend now, so that would be that would be pages slash api slash flashcards slash slack because that's where we send the HTTP requests. If we scroll down we're going to see This part right here get user from session. That is the first Span that we see there we go users find unique And then if we go down to the put request handler there we go You see the same thing happens here give me the current hub and I'll give me the current active scope but this time I'm not going to create a transaction. This time I'm going to try to get the transaction that already is created. And of course the Sentry Next.js SDK will create that for us because it's going to see that there is a header called Sentry-trace. So the SDK knows, all right, so we have a trace going on. I'm just going to create this transaction for you automatically because apparently you want to continue the trace. So here's the transaction. don't bother creating a new one. Okay, cool. We're getting that, and then we await this method, get category by ID. So if we go into this method, we're just going to see that we're just using Prisma to find a unique category where the ID matches the one that we passed from the outside. And there it is, category, find unique. That's exactly what we did. And this is possible because Sentry also has an integration that we can install to our server config. So our Prisma queries are automatically instrumented. So we don't need to create manually create spans for us. For example, if we go to Sentry-server.config.js and scroll down, there we go. into the integrations field, we can see that we have a new century.integrations.prisma, and we pass that Prisma client to the integration. So every time we execute an SQL query, the Prisma integration is going to create that span automatically for us. Again, the job for a century DevRel is hard because everything is automated and everything is just, it just works. But here we are. Okay, then we create that category checks function, span that we saw in our tree, and look what happens. We're creating the category checks span. We create or we perform the checks. If it doesn't exist, we set the status to Not Found and we finish the span. If it doesn't belong to this user, right, for example, I'm trying to edit Sarah's category. I should not be able to do that, right? Then it's not. We're setting the status to unauthenticated, and then we'll finish it. And if everything's okay, then I'm just going to finish this category check span. And basically, the checks, if you want it to know, they took 0.04 milliseconds, those two if conditions there.

Okay, moving on. Then we do the flash, get-flash part. which again, is just a... If we go into the body, it's just a Prisma query. Nothing fancy, automatically instrumented and there we go, flashcards, fine. First of that took about 80 milliseconds, right? That's how long it took for Prisma to get that flashcards back to our back-end from the database. Same thing happens here. Give me a new span, create a new span, check if the flash part is found or check if the data is okay or if it belongs to this user, etc. Otherwise just finish it if everything is alright and then do the actual updates. Again, automatically instrumented and there's this pen right here that takes 756 millisecond. At the end we just close the response, set the status, bring back the updated methods, sorry, the updated flashcards back to the client, but you might notice that we're not actually calling the finish to the transaction. That's because we didn't create it.

16. Distributed Tracing and Session Replays

Short description:

Learn how to use distributed tracing to debug applications and identify performance bottlenecks. Explore the session replay feature in Sentry, which records user interactions with your app, including mouse movements and page navigation. Session replays can be triggered by errors and provide valuable insights into what users experienced. See how to navigate the timeline and view user interactions in the session replay player. Gain a better understanding of user behavior and identify issues that may have caused errors. Session replays offer a powerful tool for troubleshooting and improving the user experience.

It's not ours to finish it. The SDK will know how to handle the finishing of the transaction. Okay, we borrowed it for a second, appended all of these extra spans to it that we want and then we let go. So the SDK will finish it and it will take it back to the client. If we go, for example, again to source slash hook slash flashcards, here's our API request that we did and all the backend spans inside. Then, for example, if the response is okay, then I'm going to create a new span which is going to be mutating cache span. I'm going to invoke the swr mutate method right here so I can refresh the data and like mutate the cache and then finish this mutating cache span which it took about 200 milliseconds and as you can see because I set the operation to cache this one has a different color than the one at the bottom because this one is a cache operation and this one is an HTTP request There we go, it's a GET request to fetch the new data. Then at the end we only have a serialized span. Just to wrap this up, wait with .json, we finished this serialized span and then we also finished the transaction at the end and this is the one that we created right? We're back in the hooks file. We finished this one because we want it to be sent to century. This is the crucial line. If we don't do this, we won't be able to see anything in Sentry. Calling the finish method will grab the whole transaction and everything that's, like the whole data, that lives in the current scope, and it's going to take it to the current hub, so the hub can send it to Sentry so that we can view it later. And this is how I instrumented the update flashcards functionality. And this is how we can see if if something takes long. Maybe one of our users will be will send us a message like updating the flashcard takes seriously too long. We should be able to see what takes the longest. And in this case, we can go straight to the update query because that's the majority of the time or duration that this request took. I'm not going to bother with the rest of the functionality. I can zero in on the actual problem right here and do something about it. So, that is distributed tracing. That's one way to debug your applications and to identify the performance bottlenecks that you might have. Next, what I want to show you is the session replays. So, Session Replace is pretty cool. Personally, it's my favorite feature in Sentry. It basically records your DOM for every user. It shows you how your users are actually using your app. Like, literally, how they move the mouse, how they navigate throughout the pages, et cetera. It works in two... The trigger can be two separate events. One is if an error happens, record, like, take the last 30 seconds, for example, around the error and send that to Sentry so we can see what the user saw on their screen while a certain error happened. And as you can see here, we have, like, nine errors here, right? And if we go to the issues here, And maybe this one has, yeah? This is the issue that Sarah created in the first part of this workshop. But if we click on the replays here, we can see that there's one replay attached to this error, OK? So let's see what Sarah saw when she caused the error to happen. If we click here, we're going to be met with this screen. So I'm seriously zoomed in, because I'm on my laptop. It's going to be a bit better for you when you open it on your end. But basically, we have a timeline of the whole user session. It's filled with these little dots, which are events. The red ones are an error. The green ones are navigation events, et cetera. And you'll see later. We'll get into it. On the left side, we have the actual player, which we can click and see how the user... what happened when the user was using our app, and the error happened. And on the right side, we have a bunch of information. But I want to show you this first. I'm going to go into the full screen and hit Play. When we don't have any... There we go. You see that? And again, this is how Sarah moved her mouse, deleted the name and clicked the update flashcard button, which caused that error. And there we go. We now create another one. We do the same thing. And if you see at the bottom, sometimes it's sped up, sometimes it's not. When there's inactivity, it automatically speeds up for you. On the right side here, you'll see the events that happen. Let me just pause this right here. For example, if I hover on this user click event, we're going to see, like… pay attention here on the timeline. When I hover on the actual user click event, we're going to see a new circle show up, and this is where that click happens. but while I'm hovering, then you'll see that this button right here gets highlighted. That's the button that the user clicked on. And if I just click on this event, it'll come back to this point, and I can hit play and see what happened there. There we go. So these are the same breadcrumbs that Sarah showed you previously. They're just being displayed to us in a timely fashion as they happened on the actual user's machine. So yeah, this is when an issue happens. So we can click here to go back to this time, to this point in time, and then just click play and see what the user did that triggered this issue. But that's not all. This is just a recording, And this is not a video, by the way, I can come in and select this. Next, it's a DOM recording.

17. Session Replay and New Features

Short description:

We're recreating the DOM into a window and masking PII information. The player allows you to inspect the element, console logs, and network requests. You can see the details of requests, errors, and memory charts. Replays are stored for 90 days in Sentry. Most dead clicks and rage clicks are new features that capture consecutive clicks on the same element. They show up in the timeline and provide more information.

We're recreating the DOM into this window here. You can also do, if you wanted to, you can also do inspect element and you'll see the actual markup of your app here. Yeah, if that's something you want to do now, let me just go back and get rid of, there we go.

So this is the recording. And you can see that we are masking the whole text right here. We don't send the PII information. You won't be able to see an email or the data or the private flashcards of the users. You'll just see stars. But you know what this screen is because you can also see it here in the URL at the top. You just won't see the actual data to the users. But guess what? That doesn't even matter to you. You want to see what the user did, not what the user saw or created in terms of data.

So that's the player. Let me just refresh, and I want to show you a new thing. I'm going to zoom out just a little bit, and that was not a little bit. That was a lot. Right here, check it out. We have the console tab. This is literally the console tab that we can see that's in the browser. this console tab so if you have console logs within your application they're going to show up here in in the console tab we forgot to add any but yeah they will appear exactly the same as they would appear in the console and you also see the network you have all the network requests which is again the same right click inspect the same thing that you will see here in your browsers network tab so we capture those as well and you can see there we are we can see all of the requests what was the requests what was the response Let's pick something more meaningful. There we go. There's the 400 one. You see how it's labeled? If we open this one, we'll see the details. What's the URL? What is the method type? It was a foot request. It resulted in a 400 status code. The body size for the request was like 121 bytes. The response was smaller. It was like 26 bytes. it took 187 milliseconds and this is the timestamp, by the way, when that happens. So we can just click here and it will jump to that specific point in time where this event happens and you'll also see that here. See how these are like a darker text and the ones at the bottom have grayed out text. That means they haven't happened just yet. So if we hit play we'll see when they happen. And they'll just go, there we go. Now it's up to here. But yeah you basically have all the data just as you're like the error happens for the user and you're literally there in the room with the user and you pop up the inspect element you check the console you check the network tab you see what they sent on what the actual requests resulted in i don't have the this one set up but yeah you'll see in all of the data right there there's also the error so here's a here are all the errors that happened during this session and if you hover on them you'll see them in the timeline. Like get highlighted in the timeline above. I'm sure you can see this. Like there's a little underline when I scrub through the timeline. The errors here get highlighted. There's also the trace tag which is pretty much the same thing that I actually showed you earlier with the distributed tracing example. But yeah, this time you can basically go back and hit play. And it will, let's see, let's go up to this point, you'll see a little line that goes through all of the spans as they happen. You can also check out the memory charts, like how the memory, the heap size, the thumbnail's memory, et cetera, was behaving while the user performed this session. And at the end, you can also see any of the tags that we captured on this specific transaction on this session. And this is session replay. This is my favorite feature in Sentry. And with this, my presentation is done. Yeah, it's pretty great. We did have a question on where are they, where are replays stored? Stored right now. We retain replays for 90 days in century. I don't think correct me if I'm wrong I don't think there's a way to set up like an AWS bucket for storing your replays No, I don't think so. I don't think there is But if they leave for example, if you sell post century then these will live in your server Yes, yeah If your century account is in the SAS version the central io then it's gonna leave on our servers If you self-deploy Sentry on your server, they're going to live on your server. We also had a question in the chat on Zoom around the session replay overhead, which we actually have a performance overhead doc on that, which I shared in the Discord and in the Zoom chat as well. So we're just about done. I'm going to share my screen one more time, and we're going to share a bunch of links as well. One more question. Yes, please. I noticed that one of the new features is the most dead clicks and the most rage clicks. I was wondering if you all could just speak a little bit to this new feature and why you like it and how you've utilized it. It's very simple. When your users are clicking angrily on your website, Sentry will pick up on that. that have like multiple consecutive clicks in the same on the same element that then we consider that as like a rage click i'm not sure about the actual condition of what's what's that click or what's a what's a rage click but yeah the sdk is able to uh capture those and you'll you'll basically get a list of the events or sorry the elements uh there we go you'll you'll see a list of the elements with that were like victims of a rage click or something else. So yeah, it'll show up here in the timeline. You can click into that to see more information and I'm going to send this link to this blog post here in a moment. So it uploads an image. Yeah, basically this user is trying to upload an image but The file picker doesn't exist, so they keep clicking on the upload image, upload image, but yeah. Exactly. And see, but that's an error that's not going to show up in – It doesn't show up. Yeah.

QnA

Wrap-up and Q&A

Short description:

It's not an actual error, but it's preventing the user from doing what they want to do. Sentry's monitoring helps developers be more actionable in resolving problems quickly. We appreciate your participation and hope you found the workshop useful. Join us for launch week next week and feel free to follow us on social media. Thank you for joining!

It's not an actual error. It's not a crash, but it's preventing the user to do what they want to do. Exactly. And you'll capture that with this. If, for example, Sentry was just crash reporting, you won't be able to be notified when something like this happens because there is no crash. Yep. No file pop-up appears. file picker? Yeah.

So real quick, just a wrap up. I'm going to send all these links. Um, here are some links you can scan this QR code or just use react summit us as a code to get three months free. If you want, I'm going to send all of these in the discord channel here in just a second. Um, actually, let me do it now. I have it already. I already wrote them all out. Um, I just need to copy and paste. That's smart. We'll do that now. So, yeah, there's a bunch of links there for you. And then in addition to that, feel free to follow us. I think we're pretty much these handles on most accounts that you can do. The slides are here, the demo repo. And then also next week we have launch week, which is where every single day we're going to have a bunch of launches related to, to Sentry. Every day at 9 a.m. Pacific time, we will have a new video launching. We'll have a conversation in Discord. You'll see it on social. So join us each day for that because that should be a lot of fun. but thank you all so much for joining us today we really appreciate you spending the last couple hours with us hopefully you got an overview that was actionable for how you can actually get it set up monitoring your applications and with the three months free with sentry hopefully you can actually give it a try too we'll stick around just for a couple more minutes uh here in the discord and in the zoom call for for chat um if you have any other questions um otherwise Thank you all so much for joining. We really appreciate it. Thanks, y'all. Bye-bye.

One person asked, what is advantages of sentry monitoring over enterprise tools like Dynatrace? I mean, I think that question is always very difficult for me to ask, sorry, answer in terms of like very specific. What are the best advantages? I would say that kind of our tagline if you will is that we try to always be thinking of the developer first rather than the like monitoring as a tool it's more like monitoring as a tool for a developer to fix a problem quickly is kind of like the biggest difference we're always trying to figure out how can we help the developer be more actionable in resolving this problem as soon as possible. So, I'm not positive. I don't know if we have like a Sentry versus Dynatrace simple little thing but I don't think I really have one. It's so hard to kind of compare them, I would say. Yeah. We definitely, I mean, and we're definitely adding a lot more. One nice thing that I really appreciate about Sentry in general is that, again, we're open source so you can jump into our GitHub discussions and give feedback on the product and things like that. We do try to have integrations with pretty much everything. All right. Cool. Again, thanks all for jumping in. Thank you very much. I'm glad you liked the workshop. We'll see you around, everyone. Have a great one.