Let's Debug Node.js Applications

Rate this content
Bookmark

In this workshop, you will learn how to Debug Node.js Applications and what best practices are important to increase the debuggability of your Node.js applications.

143 min
05 Jul, 2021

Video Summary and Transcription

Today's workshop focused on debugging Node.js applications using Chrome Developer Tools, Visual Studio Code, and other techniques. The main challenges in debugging Node.js applications are the asynchronous nature of the runtime and the event loop. The workshop covered topics such as debugging with log points, performance and memory debugging, using Visual Studio Code for debugging, and various debugging tools and modules. Participants learned how to create a PostgreSQL database on Heroku, run database migration and seeding, troubleshoot and run the project, and start the debugger. They also explored using breakpoints, lock points, CPU profiling, analyzing internal events, load testing, and hunting memory leaks. The workshop emphasized the importance of efficient code debugging and provided valuable insights and techniques for debugging Node.js applications.

1. Introduction to Debugging Node.js Applications

Short description:

Today, you are going to learn how to debug Node.js applications using Chrome developer tools, code editors like Visual Studio Code, and other useful techniques. Julian Duque and Mohith Srivastava, lead developer advocates at Salesforce, will guide you through this workshop. Julian has been involved with Node.js since 2011 and is an advocate for the project. They both work for Salesforce, showcasing the benefits of the software platform. They will be using Heroku in this workshop for its PostgreSQL database. The main challenge in debugging Node.js applications is the complexity added by the asynchronous nature of the runtime and the event loop.

♪♪ Okay. Now I have the scene to start with the workshop. Let's see. There seems to be some folks having issues finding the Discord channel. Maybe Lera can help us. In the meantime, let's start.

Today, you are going to learn how to debug Node.js applications. We are going to mainly use Chrome developer tools and also other code editors that are going to be supporting the same protocol like Visual Studio Code and some other techniques and tools that are going to be very useful to debug Node.js applications.

My name is Julian Duque. I am a lead developer advocate at Salesforce, working mainly for the Heroku team. And with me, I have the pleasure to be with Mohith. Mohith, could you introduce yourself, please? Hey, thanks, Julian. Hello, everyone. My name is Mohith Srivastava. I am a lead developer advocate here at Salesforce. I'll be helping Julian with this workshop. So really looking forward to this workshop. Thank you. Thank you, Mohith.

So a little bit about me. I've been involved with Node.js since 2011. I was part of the Node.js core project as an official collaborator until 2015. Right now, I'm a so-called collaborator emeritus because I am not doing any active contributions right now. But looking forward to get back to the project, and I'm always on the field talking about Node.js, acting as an advocate for the project as well. I'm also organizer. Well, when we were able to have in real life events of JSConf and NodeConf in Colombia, where I am from, those of the main JavaScript conference all around the world, we had the license to organize those events in Colombia. Sadly, due to the current situation globally, we decided not to do an online event, because it requires a lot of effort and a lot of work. And Lira knows about that while being an organizer of DevOps JSConference. But you have been doing an amazing job with this event, and we are super happy to be part of it. And also learning how to properly organize a virtual event to see maybe this or next year we can do the same again in Colombia. Second, thank you very much for your time. Thank you very much for joining. I'm seeing in the chat people from all over the world from Spain, Portugal, from United States, from the Netherlands, Poland. Welcome to this workshop, and let's hope you are going to learn a lot. You're going to also have fun the same fun we had organizing this content for all of you. So without further ado let's start. Also, thank you for the people that are joining super late. I know time zones can be crazy right now here in St. Pete, Florida. We are at noon pretty much, 12 10 p.m, but there are some other folks I'm seeing in the chat joining at 12 in the morning in the Philippines, so I know it's going to be a great effort. If for some reason you feel tired you need to go to sleep or you have some other things to do, the guide is complete. You can follow it on your own time, the link is going to be available, you are not going to need me pretty much, we are here, Mo and myself, to help you to guide you in the full process with the workshop, help you with any issues you are finding but you can follow the workshop along if you want it so. Oh I'm seeing some other folks from St. Pete Florida as well. Kevin, hello! I hope you are enjoying this a little bit chilly morning here in St. Pete but beautiful weather we are having today. So let's start. I'm going to start with a presentation. This is going to serve as an introduction to the topic of debugging Node.js applications. You can find the slides on the workshop guide that I already shared with you here on the Discord chat or on the Zoom chat. I'm seeing more folks joining from Florida, Nikolaj from Fort Lauderdale. So, awesome to have people from all over the place and including my current home state which is Florida. So, as we already introduced ourselves, I'm Julian, I'm here with Mohith. We both work for Salesforce as lead developer advocates. We are trying to show the benefit software platform. And if you don't know Heroku is part of the Salesforce platform. It is a platform as a service so you can run your applications not only Node.js but we also support other languages. We are going to be using Heroku in this workshop for two main reasons. One, we need a PostgreSQL database, but if you have a PostgreSQL server running or if you want to use your own instance feel free to do it. You don't need to use Heroku. It's going to be optional, but for simplifying the process of having a database we are going to be using Heroku for that. And I also stream some content on Twitch sometimes. I'm going to start again mainly in Spanish because I'm a native Spanish speaker, but we together also streamed content on Trailhead Live which is a platform that we have for education at Salesforce. You can go to trailhead.salesforce.com and you're going to see a bunch of the videos we have created or we are also streaming live on YouTube on the Salesforce Developers Channel. You can see a bunch of content from us. We have been talking lately a lot about Node.js and Lightning Web Components, open source and some other technologies we have been working lately. Let's start with the content.

So what are the main challenges while debugging a Node.js application? The first one is that debugging is synchronous workflows are going to add a little complexity. Node.js is an asynchronous runtime. It has this concept of the event loop, which is a single thread that we have available for our applications and all of the different asynchronous workflows are going to be scheduled on that single thread using the event loop.

2. Debugging Node.js Applications

Short description:

To debug Node.js applications, you can use Node inspect to enable the B8 inspector, which is the official debugging protocol for B8, the JavaScript runtime used by Node.js. There are two flags, "inspect" and "inspect-break", that you can use with the node binary to enable debugging mode. The first flag allows the server to continue execution unless a breakpoint is set, while the second flag adds a breakpoint at the first line of the application. The official debugger for B8 is the Chrome Developer Tools, which can be accessed by opening Chrome and typing "chrome://inspect" in the URL. From there, you can configure your targets and debug your Node.js application by adding breakpoints, controlling execution, and exploring variables and the call stack.

If you are using promises, there is also the runtime microtask queue, which is something complex. Normally, when you have stack traces and errors, that asynchronous layer is going to be hidden for you. So it's going to be difficult when you are going to see an error and you just see that the error happened on a timeout and you don't know where to look for. Lately, BA, which is the engine that Node.js uses, the JavaScript engine that Node.js uses, has been adding a lot of ways to have more visibility on the asynchronous layer of Node or JavaScript. So now, after I think the version 10 or 12 of Node.js, if I remember correctly, you are going to have access to asynchronous stack traces while you are on the debugger. And we're going to see that later when we start debugging our Node.js applications, that we will be able to see the stack trace with the synchronous operations. And there is also another thing that I will not cover directly on the workshop, but I'm going to mention it in the introduction, which is the post-mortem debugging. Post-mortem debugging is when your application crashes for some reason, there is a memory overflow, or something crazy happened to your application, and you have a core dump. You have something that has a lot of C and C++ information in there, that are coming from the V8 runtime. And in order to debug that, you will need to have C and C++ tooling skills. So, you will need to use LLDB and some other tools that are going to be a little bit complex for regular JavaScript developers. They are even complex for me, that I've been working with Node for a while. So, it requires, like, a little more knowledge to be able to deal with this type of situation. So, those are the main challenges when working with Node.js apps and debugging those Node.js apps. So, how to debug Node.js applications? This is going to be covered in the workshop. We have an exercise for you to do it on your own computer. So, in the meantime, take a look at the prerequisites we added on the guide, make sure you have Node.js installed, you have a free account, and the CLI, so we will be able to have access to a Postgres database or have a PostgreSQL database running on your computer. Docker is going to be optional. I'm going to be showing how to debug a Node.js application running in Docker, but if you don't have Docker or if you don't want to install Docker, that's fine. You will have the instructions in there, and Visual Studio Code is also going to be optional. We recommend that code editor is super awesome and easy to use, but if you use a Beam or Emacs or JetBrains or any other code editor, feel free to continue with the workshop because we are going to mainly use the Chrome Developer Tools. That's going to be a requirement. Please install Google Chrome or if you are on Linux, you can also use Chromium, which is the open source version of Google Chrome, both are going to work for the purposes of the workshop. So first you will need to choose your own weapon to do debugging. And I found this tweet pretty relevant for the talk. Choose two, you are going to be using console log debugging. I use a lot of console logs for debugging, or you are going to use the debugger keyword, which is a BH supported keyword to add breakpoints into your code. Or let's use a debugger. Let's use a code editor or something that lets you pretty much add breakpoints to your source code and navigate using the debugging tools. Or let's start a debugger from Visual Studio Code. Or go to Twitter and complain or to Slack or to other social networks to see what's going on and ask for help for people. Or if this is getting crazy or very difficult, let's go to Stack Overflow, which is going to help us a lot with the process. Choose your weapon. What's the weapon of choice for debugging? Let us know on Discord or let us know on the chat. What do you usually use for debugging your Node.js applications? Console log is fine. It is okay. We are going to see a better alternative at the end, than console log for debugging, but that's something that a lot of developers uses. And I personally use debugging options as well. Excellent. There are people replying now they use the option 5, other people use console log, etc. That's pretty nice. Okay. The official way of debugging Node.js applications, it's using Node inspect, so Node Inspect is a way to enable the B8 inspector in Node.js. B8 inspector is the official debugging protocol for B8. B8 is the JavaScript runtime that Node.js uses. In order to enable that B8 inspector, there are two flags that you can use with the node binary. One is the,"inspect", and the other one is the,"inspect-break". The first one is going to enable debugging mode on your Node.js process, but it's going to continue the execution of the server without any interruption, unless you are already connected and you have a breakpoint in place. One of those breakpoints can be the debugger keyword that JavaScript supports. If you have that debugger keyword in any part of your code, then that code path is going to be loaded while running your application. Your application is going to just pause in that specific breakpoint. The other one, the node-inspect-BRK, is going to add a breakpoint at the first line of your node.js application. This is going to be very useful if you want to debug the bootstrapping part of your app. The bootstrapping part of your app is when your app loads before the server starts. If you want to debug the initial requirement of files, the initial configuration, using the second option is going to be the best way to start debugging your application. So, take these two into account because we are going to be using those in our workflow. Then, since we are using V8 inspector, the official debugger for V8 is called the Chrome Developer Tools. The Chrome Developer Tools are part of the Chrome browser or the Chromium browser, which is the open source version of Chrome. What you need to do is open Chrome on the browser URL type Chrome colon slash slash inspect and it will open this view where you will be able to configure your targets. This is like the remote debugging view from Chrome. You will be able to configure your targets depending on the port that the debugger is running. By default it's going to be running on port 9229. For the purpose of our workshop we changed that port a little bit, so we don't have any conflict with another application that is running. And also you can know how to configure that as well, maybe if you want to do remote debugging later. And after you have that, you can see that you have the target and there is a link, instead of clicking on the target to inspect in the second line here, we are going to be clicking on the open dedicated dev tools for Node, which is going to open a specific view for the different Node.js applications that we are going to be executing. Don't do this yet, this is just an introduction. We are going to be doing every step one by one on the workshop guide. So, for Chrome DevTools, you can debug your Node.js application by adding breakpoints, controlling the step-by-step execution, explore variables, explore the call stack. Here in the call stack, you will be able to also see the synchronous stack trace. You have the regular navigation tools from a debugger.

3. Debugging with Log Points

Short description:

You can add log points to your code instead of using console logs everywhere. Log points work like breakpoints, allowing you to write an expression that will be executed or analyzed every time your application passes through that line. The output of the expression will be sent to the console panel. Console log is not recommended for production environments due to its blocking nature. It's better to use a log library like Winston or Pino to manage logs properly.

You can step into a function call. You can go ahead and continue the execution of the scripts. And you can also have a panel to watch for variables. Maybe you are going to watch for the input request of an HTTP client. You are going to watch for a request.body. You can add log points. They're like a different other tools that you can have from this specific debugger.

One thing instead of adding console log everywhere, a good way to start debugging for messages is to add log points. Log points are going to be supported on the Cron Developer tools and also Visual Studio Code as well. Log points work similarly to a breakpoint. You are going to add a log point on a specific line of code. And in there, you can write an expression. And that expression is going to be executed or is going to be analyzed every time your application in debug mode is passing through that line. And the content of that expression is going to be sent into the console panel. So you will be able to see the output in there. Very useful for debugging instead of adding console logs all over the place.

And there is also one thing with console log that you need to take it into account is that console log, it is not recommended for production environments. Why? Because console log is a blocking operation. A blocking operation means that for that specific moment that console log is being executed, the event loop is going to be blocked and the output is going to be sent into the terminal. If you are going to have logs in your application, it is better to use a log library, you can use something like Winston, Pino. There are like some other different tools to be able to manage logs properly that are going to treat logs on a different way. They're going to be using a streaming to the standard output interface, or they're going to be a streaming the logs into a server. There are different ways to treat logs in production. For development, they are okay, but for production, console log is not recommended. It might add performant issues to your application.

4. Debugging Performance and Memory Issues

Short description:

In the workshop, we will explore debugging performance and memory issues. Chrome Developer Tools will be useful for hunting down memory leaks and profiling the CPU. We will have exercises to identify memory leaks and analyze CPU performance. Tips for debugging Node.js applications include starting the debugging process while the application is running and using signals to enable debugging. Adding breakpoints using the debugger keyword is not recommended due to potential issues.

And later, when we are going to be debugging performance on our workshop, we are going to see that console log has some overhead. Let's continue with Node Inspect. Besides doing the regular step-by-step debugging, with Node Inspect and the Chrome Developer Tools, you will be able to also profile the memory of your application. You will be able to take heap snapshots, take a look of the memory object, of the objects that have been allocated in memory, and you will be able to hunt down memory leaks.

A memory leak is when you are retaining or holding on to an object that is not being released by the garbage collector, and the memory is going to be increasing until we reach a limit and our application crashes. And we don't wanna have memory leaks on a production application. This is why Chrome Developer Tools are going to be super useful for us to be able to hunt down those memory leaks. We will have an exercise in the workshop that the application that we are going to debug has a crazy memory leak, and we are going to use the tools to be able to identify that memory leak. We will not fix it. That will be for you as an exercise. You can provide any clever solution to fix the memory leak we introduce in the code. Bonus points if you submit a pull request, but we can discuss that once we get into the specific section.

And also, you will be able to profile the CPU. And we also have an exercise when we are going to do a small load test on our application, send a bunch of traffic, and we will be able to take a CPU profile and take a look what the CPU is doing in our application, how the function stack trace or the function calls are going to be looking in CPU and how much resources they are using. And Altarca is asking if the workshop is being recorded and according to Lira, it is. So you will have a recording later.

Some tips that are very useful while debugging Node.js applications. You can start to debug Node.js applications while the application is already running by using the usr1 signal. You can send that signal using the kill command on that process ID. Why this is useful? Instead of starting your process with Node inspect, maybe you wanna start debugging your application while your application is hot. What that means? Your application has been running for a couple of days, it's memory is overloaded and it had real traffic and you might want to start debugging at that point. If you stop and restart the application, you will lose that context that has been already loaded into your app. So a good way to enable that debugging protocol is to send a signal to the process and it will enable the debugging. And the other one, you can also add breakpoints as I told you on your code using a JS keyword, the debugger one. But I personally don't use this or don't recommend it. Sometimes we forget about removing those specific breakpoints in code and or code is going to pause and we don't know why while we are doing the debugging.

5. Visual Studio Code for Debugging

Short description:

Visual Studio Code is a powerful code editor that supports the same debugging protocol as Chrome Developer Tools. It allows for local and remote debugging, with customizable debugging configurations. You can debug your application without leaving the code editor, making it convenient and efficient.

So it is better to have the breakpoints added by the debugger. Then we have Visual Studio Code. Visual Studio Code supports the same beard inspector protocol and it is a great tool for local and remote debugging. Why it is good to debug on Visual Studio Code because in the same code editor that you are writing the code, you are going to debug your application. You don't need to leave your tool and that's it. You can also have different debugging configurations. Visual Studio Code is very customizable. So you will have a launch.json file with different debugging options depending off the environment variables you wanna set on your application, different scripts you wanna debug, if you wanna debug the tests, if you wanna debug different NPM script. So it's very good for also with just one click start debugging in the configuration you want.

6. Debugging Tools and Modules

Short description:

Other code editors like WebStorm and Adam also support the BA Inspector protocol, but only for the debugger portion. For memory, profile, and performance debugging, you need to use Chrome Developer Tools. Visual Studio Code can add lockpoints and has multiple debugging configurations. NDV is a Chromium-based standalone Node.js debugger with extra features like child process debugging and black boxing. LLNode is a tool for post-mortem debugging, useful for debugging core dumps. Debug is a console-based debugger module that supports namespaces and can be enabled using an environment variable. It is widely used in the NPM ecosystem, including projects like Express. Trace and Clarify are libraries that expand stack traces with asynchronous information.

Other ideas like WebStorm from JetBrains, Adam, and some other code editors also support the BA Inspector protocol. But the main caveat is that only works for the debugger portion. You will not have neither memory or profile or performance debugging on Visual Studio Code. If you wanna do memory or performance you will need to go to the Chrome Developer Tools to be able to do that.

Some tips, Visual Studio Code can also add lockpoints similar to Chrome Developer Tools. Right click on one line, add a lockpoint, then you write a JavaScript expression that is going to be evaluated and the content is going to be sent to the console instead of having multiple console locks all over the place. And you can have, as I said before, multiple debugging configurations. If you wanna have a configuration for Docker, configuration for a remote process, configuration for your application running on production, configuration for your application running on a staging, you can have all of those different configurations on Visual Studio Code and that will be simplifying your life.

There is another tool I added as an optional in the workshop. I am not covering these, but you can use it and start playing with it. It is NDV or node debugger. It is a Chromium-based standalone, Node.js debugger. This was created by Chrome Labs. Sadly, it is not maintained anymore. The last commit was in 2019. But it comes with some extra features that Chrome Developer Tools doesn't support. One is child process debugging. Chrome Developer Tools doesn't support debugging a process that has been executed using the child process module. The child process module allows you to not only run a external command from Node.js, but also a spawn a new Node.js script as a child process of your application. NDV will be able to debug those child processes. Second, NDV supports black boxing. What this means is that all of the Node.js internals are going to be black boxed. They are not going to appear in the Kali stack strays when you're going to be debugging, when you are going to debug your Node.js application, code is not going into the Node.js internals because it's going to focus only in the code you already wrote. So that's a very good feature. And second, it supports Edit-In-Place, so it can serve as an IDE as well. If you want to do some changes into your code and continue the debugging, NDB supports that. So those are like the main three features that NDB supports. You can install it by running npm install-gndv. It will take some time because it will download a Chrome-Uni runtime. I think it uses Puppeteer or something like that. And you don't need to install Chrome. Pretty much you run NDB and the script and it will load the same Chrome developer tools that we are going to be using, but with some extra features that I already mentioned.

LLNode is the tool I mentioned for doing post-mortem debugging. This is a plugin on top of LLDV. LLDV it's a debugger for LLVM binaries, and is going to be useful for debugging core dumps. So a core dump is a file that contains some information after a segmentation fault happened in your Node.js application. You can trigger this segmentation fault by executing process.abort instead of process.exit in your Node.js application. And one thing, if you want to have that core dump, your operating system needs to support core dumps. So it needs to have that option enabled. So to have that option enabled, I think in Linux, you need to use the ulimit option to be able to enable core dumps and use this process.abort to be able to generate that information. You can find more information on the llnode repository and there is a good kind of intro of how llnode works. They're like an animation here that we'll show you pretty much how this tool is going to be working for Node. What you are going to be doing is debugging C and C++ information and llnode augments the C and C++ objects to support JavaScript and BA symbols. So that way you will be able to take a look at the memory that the application had before it crashed and maybe identify a memory leak from lldb. But as I mentioned before you will need to have some skills by using the C and C++ tools that I personally don't have. And this is why I'm not covering this concept in the workshop but I am mentioning it if you wanna take a look and get deeper into postmortem debugging. So take a look at the video that Federico Dudni one of the most prolific code contributors for Node.js have created and you can level up your skills while debugging applications after they have been crashed.

Some useful MPM modules we are going to be covering in one of those and the other two are for you to explore. Devug allows you to have console-based debugger that can be enabled using an environment variable. This is the better alternative to console log that I'm going to be telling you to use. You normally when you run your application this debug information is not going to appear into your terminal until you specifically tells your script to enable that module by using the debug environment variable. It supports name spaces so you will be able to have debugging logs depending on the modules you are creating. Maybe you want to have debug logs for your database layer for your fronted layer, for your services layer and different other parts of your code and just enable those directly on the environment variable. We have an exercise the code is using some console logs and we will ask you to refactor to use the debug instead. But this is an example, how to use the debug. It will give you a function that you can use as if it were a console log file, a console log function call sorry. And then in order to enable that you will need to set the name space to the debug environment variable and execute your project and you are going to see some color output from the debug module. Why debug is good or useful is because it is used by a lot of other modules in the MPM ecosystem. Express and some other projects like SQLites, et cetera already use debug for debugging messages. So when you add the same module to your project and you start debugging your app you might see also some output from other libraries as well. Here you are going to see the express application namespace from the Express library. All of the different debugging information that it gives you and that might be useful for you to identify some other issues as well. Remember that I mentioned that by default Node.js hides a lot of information especially asynchronous information on this stack traces where your application crashes or has any issue. You have that information hidden for you. On the first screenshot, we have a specific error in one asynchronous route. When we take a look at that, we say that something crashed on a timeout and it doesn't give us any more information. Yes, it fail on a timeout but what's the name of the function? Let me know what really happened on my app. Trace and Clarify are two libraries that are going to allow you to extend or expand the stack traces by having the asynchronous information. These modules are very useful for development purposes. Don't use these modules on production because they are going to add some overhead.

7. Setting Up for Node.js Success

Short description:

To use trace and clarify to augment your asynchronous stacktraces, save them to your app and specify the stack trace limit. You can also use log points to simplify the output. Make sure you have the prerequisite set, including JavaScript and basic Node.js experience. Use Node.js LTS, have Node.js 14 installed, and consider using Volta for managing multiple versions of Node. Install Autocannon for load testing and optionally NDB. You will need GIT, a GitHub account, Google Chrome or Chromium, a Heroku free account, the Heroku CLI, Visual Studio Code (optional), and Docker (optional). The workshop has not been tested on Windows, but you can use the Windows subsystem for Linux. Mohith is not familiar with debugging Deno applications, but it may have similar challenges to Node.js. Clone the GraphQL API project and install dependencies. Configure a Postgres database using Heroku or your own Postgres instance.

This operation is going to be an expensive operation. So in order to use this, you are going to save trace and clarify to your app and then you can specify the stack trace limit and start tracing your application. If you see on the second screenshot now after the synchronous information in gray, it will tell us that the exception happened in the bomb function. I created a function called bomb, when you execute that, it pretty much will explode your application. But it's telling you exactly what function cause the issue. And that's something that is already hidden by Node.js because this is an asynchronous workflow. So very useful if you wanna augment your asynchronous stacktraces, clarified pretty much what it does is just focus on the information you need and simplifies the output. But you can use those two modules together. And that's the introduction for these workshop. Thank you very much.

Now let's get our hands into the content. So you might already have this guide. These guide, it contains the full worldshop. Make sure you have all of the prerequisite set. You will need to have some JavaScript and basic Node.js experience. It is good if you don't have those, you can follow the workshop if you don't have that information. But it's useful to at least have a better knowledge of what you are doing. We are going to be using Node.js LTS, which is the long-term supported version. It is the version that is recommended for production. Make sure that you have at least a 14th version installed on your computer. There are like three different ways of installing it. You can use the official binaries, download the official binary for your computer and install it. You can use NBM, which is the Node version manager, or my favorite is using Volta. Volta is a tool for managing JavaScript run times and different modules. It's very easy to use. And from here, you can run Volta installed Node that you can have multiple versions of Node installed in your computer, switch those versions, being those version for a specific project. So it's a tool that is very good for us developers that work on multiple projects. We will use the following global MPN modules. We will use Autocannon. Autocannon is a tool for do load balancing. Sorry, load testing. We are going to be sending traffic to our application, like a bunch of different requests, instead of hitting refresh, we're going to use an automated tool to send some traffic to our app. So make sure you install it globally. And you might wanna try NDB or not. This is totally optional for you. You will need to have GIT and a GitHub account, a GIT to be able to clone a project, the project you are going to be debugging with us today, you can also use your own project later, but the guide is written for the specific project that we already created, you will need to have Google Chrome or Chromium installed in your computer, because we will use the Chrome Developer Tools. You will need to have an Heroku free account, go ahead, register for a free account, totally free, you don't need your credit card. If it asks you for your credit card, you can click on a Skip, the main benefit of adding a credit card is that it will give you a thousand hours a month to run a web application, well a month has more than a thousand hours, but that's also useful for having a worker process or something running on Heroku. You will need to have the Heroku CLI installed because we will use it to create a PostgreSQL database instance on Heroku that the application needs because it uses a database. Visual Studio Code is recommended but you don't need to use it, this is just for the specific Visual Studio Code section and Docker as well. Docker is gonna be optional if you wanna do that section, if not, that is okay. We are going to spend most of the time with Chrome Developer Tools. One notice, one information is that this workshop has not been tested on Windows, this has been tested on Linux and Mac but you can still use Windows but using the Windows subsystem for Linux because most of these commands are like ready for a new mix environment. Windows have a different way to dealing with environment variables and some other things that I personally don't have a way to test those, I don't use Windows as a development machine, I use Mac or Linux for that specific purpose. And that's it for the introduction, Mohith do you have anything to say to our group?

Yes, so I have a question here from an anonymous attendee, so the question is do you know if Deno solves some of these debugging challenges right out of the box? I don't have experience with Deno, sadly I just had like a very brief experience, not sure how to debug at Deno application, so can't answer that. I might say that it's very similar, since it's a new runtime it might solve some of the challenges, but those challenges are not specifically of Node, they are specifically of JavaScript per se, so maybe they are having the same issues with asynchronous things. Not sure how Deno handle those asynchronous workflows, I will need to put that on the list for things to research.

Okay awesome, yeah, I did some research as well and I was able to find out that Deno also uses the same V8 engine and the same protocol for debugging as Node, so very, very similar to the stuff that we have here. Awesome, so thank you for your question and I will be playing with that later in the future to see how Deno works with those challenges and how to debug Deno applications. I will say it's going to be similar and let's continue. Okay. Let's get it started. Go, click on the get it started and now we will start working with our project. First, we will need to clone this project from Git. This sees a GraphQL API written in Node.js it is using Apollo Server. Apollo is a GraphQL runtime, which it's compatible with Node. We are using Express as the HTTP framework for this application and we are using SQL Lies as an ORM. These application have two different models. One is properties and the other one is customers. These applications is called GraphQL API. Think of it as if we're building a rent application that has a lot of different properties and a list of customers. Don't over complicate these. We are going to be using this as a basic application to do some debugging, to explore the code. But we are not going to be using this application on any other concept. So make sure you clone the application and then go to the folder and run npm install to install the dependencies locally in your computer. Second, we will configure a database. We will use Postgres. The project is pretty much created to work with a PostgresQL database. If you already have Postgres running in your computer and you have the connection string and you have access to the Postgres interface, feel free to ignore these steps if you want. But for the simplified purposes, we are going to be using Heroku to create a PostgresQL add-on on an application.

8. Creating a PostgreSQL Database on Heroku

Short description:

To create a PostgreSQL database on Heroku, make sure you are logged in, create an application, and add the database as an add-on. Download the database URL environment variable into a .env file using the Heroku config command. Load the environment variable into your terminal using the export command. This is necessary for running the migration and seed commands. If you need help, refer to the prerequisites for installing the Heroku CLI and creating an account. We are here to support you during and after the workshop.

And we will run the migrations and a seed file which contains some fake data for our app. Make sure you are logged in into Heroku, then run Heroku create with an application name. This application name needs to be unique or leave it blank and it will autogenerate one for you. And then you're going to run this command to create an add-on or a PostgresQL add-on on the Heroku application.

So somebody is asking for the link, let me go ahead and share it. Oops, I forget that I have a different computer here. Let me share it for Warren Gonzaga. Warren, that's the link of the guide and for the rest of the people, you can start following in there. Perfect, so let's do this. Let me open a terminal. First, I'm going to check that I am already logged in into Heroku. If you are not logged in, you will need to run Heroku login. Heroku login is going to open a browser, will ask for your credentials, will ask you to authorize the CLI. After you authorize the CLI, you will be able to use Heroku from here. Then let's create an application. I'm going to create an application called jduke-rent-api. So I created a space to run my application. We are not going to be deploying this application yet. That's for the remote debugging section. Right now we just need a database and I'm going to be using a database that is going to be hosted on Heroku. This database here, this command that I'm going to copy, it's a free PostgreSQL database that you can use. It supports up to 10,000 rows, and one gigabyte of space which is going to be way more than we need for this application. So let's create a PostgreSQL database on our app.

Perfect, now that we have the database, it is that fast, now that we have that database, we need to get the database URL environment variable. So let's do something to download that information into a.env file. So we are going to be running this command. Heroku config dash dash shell, and sending the output to the.env, to the.env file. So, Nikolai ask, Heroku is in recognized as a command, where do we get it from? So Nikolai, you are going to the introduction here, where it says on the prerequisites that you need the Heroku CLI. Click on that link, and it will take you to the download and install for that specific command. So if you add a Mac and you use brew, you can use this. You can download the installation from Windows. You can do it from Ubuntu, or something that is very hidden here, is that you can use npm to install Heroku. You can do npm install-g Heroku and it will install it for you on your computer. So go ahead. Run that command, make sure you have Heroku, and make sure you run the Heroku login so you have access to Heroku. Create an account. For creating an account, you can go to signup.heroku.com. signup.heroku.com is going to ask you for some information. And from here, you will have free account. Okay? And remember, this workshop, you can do it on your own time. I try to document it pretty well with all of the different steps. We tried everything to make sure you can do it by yourself on your own time. You can repeat it. Our Twitter accounts are open. If you have any question after the workshop, if you want to do this next week, we will be available to support you as well. So let us know if you get behind for some reason, don't you worry, the idea for you is to have this content and to play with it with way more time. And thank you very much for the feedback of the document. So, we are already logging into Heroku. We already created the application. We already created the add-on and we downloaded the configuration into a.env file. What is this Heroku config? So let's run that Heroku config. Heroku config is going to keep environment variables into their Heroku application space. Here, you are going to find that database URL environment variable with the connection string. When I run Heroku config shell, is going to give me that information without format. That format is for a shell, for a terminal that I have here. And then I've redirected the output into a.env file. So later we are going to be using these.env file for our application. So what we are going to be doing next is to load that environment variable into our terminal. This is needed because we are going to run the migration and the seeds. The migration are going to create the tables in Postgres and the seeds are going to add data in Postgres. So you need to run export and the contents of the AMP file here, for example, something like this. So this is what I'm going to be doing. Selecting the output of.amp. You can use cat to output the contents of the file into the terminal, cat space.amp. Then running export, pasting that URL and that's it. If you do echo $database. That's a way to access database in Bash. You are going to see that now that variable is set. So make sure you have that variable set in your environment before running the next command. If you need any help, let us know in the chat, Mohit is going to be pending, helping people, helping folks in the chat, but we want you to follow the workshop along and to be able to do the same things we are doing right now.

9. Running Database Migration and Seeding

Short description:

We use NPX to run the database migration and seed command. The migration files create the database tables, while the seeders generate fake data using FakerJS. Additionally, you can use PSQL to access the PostgreSQL database from the terminal and run commands to navigate and query the database.

Cool. Then we are going to be running NPN. Sorry. NPX, which is a script that executes commands from NPM without needing to install these globally in our computer. So we are going to be using these to run the database migration.

So let's copy the database migration, paste it into the terminal. And it's creating the customer table and creating the property table. Cool. And second, let's run the seed command. It's going to seed my database with data.

So I have some scripts. If you want to take a look, please, I love when people go and take a look at code. Let me open the Visual Studio Code to show you what to see. There are the migration files. These is the files we are running, the file that creates the database tables in the PostgreSQL database that we created. And the seeders are the ones that create a bunch of fake data, a bunch of random data. We are using FakerJS, FakerJS is a very useful tool for tests to create random data without having like big files of information. So I'm creating like a thousand of customers with fake names, emails, phone numbers and et cetera. This is pretty much to fill out all our database with information.

One command that it is not on the workshop, but it is very good to access the database instance, is the following. You can use PSQL, which is the repl interface to open PostgreSQL from the terminal. You can run PSQL on the database that you already provisioned from the Heroku CLI by running Heroku pg, which is the PostgreSQL plugin, colon PSQL. You don't need to provide the credentials, the username, password, or anything like that. We just run in that command, you have access to the PSQL interface. From here you can run commands like show me the relations that my database has, which is backslash D. Now you can see that we have the customer stables in there, so we can do some select all from customers, and you can see that there is that fake data that was created into our application. This is just a useful tool that you can use to navigate your newly created database. And let's exit by running backslash quit.

10. Troubleshooting and Running the Project

Short description:

Could you tell me why running those commands I received you're unable to resolve SQLis package? What version of Node.js are you using? Let's try to run npm install-g-npm-at-7 to update npm. The Heroku PG-PSQL only works if you have Postgres installed locally. You can use any ORM for the workshop. Make sure you have run the necessary commands for data to be loaded. We have three scripts to run the project: NPM start for production mode, start dev for development mode, and start divoc for debugging mode.

Could you tell me why running those commands I received you're unable to resolve SQLis package. You're unable to resolve SQLis package. Which ones are you running are the NPX, SQLis, CLI ones? Okay. What version of Node.js... What version of Node.js are you using? Or version of npm? Run npm-b. Let me know, npm-b. 4.14 is good. Maybe it is because it is npm-6. Let's try to run npm install-g-npm-at-7 to update npm.

So Julian, there is one more question there, which says the Heroku PG-PSQL only works if you have Postgres installed locally, right? Uh... The Heroku command, the PG-PSQL. The PSQL, oh yeah, maybe. It only, yeah, you know, that is correct. And I have validated it actually, before that it requires Postgres installed on your local. And you have to be running that server to run that command. Okay, I didn't know that, I didn't know that. Thank you very much Mo for that.

May I use other ORMs, Prisma 2 to be exact, radiant SQLite? You can use whatever you want. Right now this project has SQLites. We are just setting up the project that we are going to debug. But the workshop will work on any Node.js project. And you can use all their different ORM if you want to use a PostgreSQL database in Heroku. That's up to you. This is because we had already this code running with SQLites. But you can use the any other library, even the native PgDriver. You can use Next, you can use any other as well. So it's up to you the different project that you are going to use for the workshop. Right now we are going to be using these. If you wanna use another different project, the ones you are writing right now, the ones you are working on right now, feel free to do it. The same things are going to work just the screenshots of the line numbers and the other stuff from the activities are not going to be working as well. So HerokuPGP-SQL select asterisks from customers does not show any data. Are you, have you run the MPX SQL ICLI DV migrate and SQL ICLI DV seed all. And those showed like the success open like the one we have here. If you have any error, it might not work. It might not contain data. If you have output, it worked. So just to make sure you have the output in there. Okay, it says OccupyGESQL, the local PESQL command should not be located. Oh yes, you will need to install that. Are you using? I forgot to add that on the workshop. So we will need to update the workshop instructions to let people know that they need to have PSQL installed. So sorry, I missed that specific part. Try to npm install SQLite, then use the npx command. Oh, nice, that's a good option. So remember that before everything you need to run npm install, when you're running npm install, it will install all of the different dependencies that are set in the pack as JSON. And one of those dependencies is going to be SQLite. Nice, so make sure before running anything, run that npm install command. Do I have it here? Yes, is the first instruction. You will need to go to the folder and run npm install. Maybe we need to separate those so they are more clear, not good. Just keep troubleshooting, we are almost done. We just need to have the data loaded into our application. Once it is loaded, we can continue. If for some reason this is not working, use another Node.js project, it's going to work as well.

I'm going to continue to explaining the last three things that we are going to be using for the project. How to run the project, so we have three scripts that are going to be used to execute the project. One is NPM start, this will start the project on production mode, this will be used when running our application on our final server. Once we deploy this to a Roku, it will execute NPM start or directly the server.js script. The other script is the start dev. Start dev will start the project in development mode, this uses NodeMUN to be able to restart the project or restart the server if there is any error or if you change your code, very useful for development mode. And the other script is the start divoc, is the one that we are going to be using to start debugging our application. You can go to the package JSON, take a look at this script section to see how we are enabling the start, the start divoc and the start dev commands. Here, you can see that the start divoc is going to run node inspect and will listen on the port 9292 and run the server.js. Development mode is going to execute NodeMUN to run the server. Thank you, Mohit, for sharing the instructions and sorry I forgot to add that we needed to have PostgreSQL, at least the client, installed on the computer. I think with Mac, there is a brew install psql command. How to start psql on Mac, yes, I think there is a way using brew or if you are on Linux, there is also ways to install in that client. Thank you, Mo, for sharing the documentation.

11. Starting the Debugger and Troubleshooting

Short description:

To start the debugger, run node inspect or node inspect break to enable debugging mode. You can specify a port with the equals option. Another way to enable debugging is by sending a kill signal to the process ID. Add the PID to your log for easy debugging. For Windows users, install cross-env to solve the node-env error. Check the PGPSQL and database configuration if you're not getting data from GraphQL. Make sure the dvmigrade and dvseedall commands have the expected output.

How to start psql on Mac, yes, I think there is a way using brew or if you are on Linux, there is also ways to install in that client. Thank you, Mo, for sharing the documentation. Yeah, no worries.

So, let's run our project. Let's run npm run, Start dev. Now, our project is running and you are going to be seeing some output once we open this. So, let me open this. Right now, when you open the project, when you open the local host 8080, it will open these GraphQL playground. The GraphQL playground is a way to debug GraphQL, a way to debug a GraphQL API. Sorry, we have it enabled on this project so we can easily send queries to our app. And if you see here, we have some output. This is sending the number of operations that GraphQL is receiving. Right now there is some introspection query that we are receiving automatically every two seconds. That's something that the GraphQL playground is doing pretty much to get the schema information. Here you can get the schema information with all of the different queries that we have on our application and the different GraphQL objects we created. Here you can run the queries. There is one query that I share with you on the guide that you can pretty much copy and paste, paste it on the playground, click on play, and it will return some data. And if you go to the terminal, now that you can see that we have executed the list customers once. And when we execute the list customers it's going to go to the database. Let's run it multiple times. And now we can see that we have executed that eight times. It's to keep some stats. And there is another route, which is a slash stats that will return that object. We will use this later for debugging purposes. I'm just telling you how this application looks like.

Now, let's talk about the no debugger. Which I mean, we came to this workshop to learn about debugging node js application. And we have been talking for an hour and we haven't started yet. So, as I told you to start the debugger, you will need to run node inspect. Node inspect, we enable the debugging mode, It will support the V8 inspector protocol. I have added some links so you can read more from these guides. And you can also specify a port while running the inspect with the equals option. You can see on the pack as Json that here we add specifying the port 9292. Then you have the inspect break that will break on the first line. So, very useful if you wanna debug the bootstrapping of your application. The bootstrapping in this case is going to be on the server.js file. The initial configuration. So it's going to be adding a break point in the first line. And from here, you will be able to start debugging your app before the server is even listening. And there is also another way to enable debugging while your application is running by sending the kill signal on the process ID. So let me stop the project and show you something. When you start the project, hitting the log, I am already sending you or giving you the PID, the process ID. If you go to the console log, I am adding the process PID into the log. So you know what's that process to send the signal. And that's one pro tip that I add here. So always add the PID into your log. So it is going to be super easy for you to enable these debugging mode. Let me send a signal to that PID, the user1, and when I send the signal, you can see that the debugger started and now I am ready to start debugging my application. So that's a very good way to start working with an already running Node.js app. Cool! But if you wanna start directly on debugging mode, let's do npm run startdebug. And now my application is running on debugging mode on the port 9292. For those who are using Windows and have the following error, node-env-development-nodebond-server, node-env is not recognized, you can solve it by installing cross-env. You can read on this court, Juan Wagner is already solving that issue for us. Juan, you are amazing. A good way to make this project cross platform. As I told you before, I didn't test this project on Windows, but thank you Juan for helping all the people working with this. Thank you, you deserve a star.

Brita, a little help. Please, I got nothing when I pressed play to get the response from GraphQL. Brita, maybe check this to see if you have data. Run the PGPSQL and try to get customers from the database. If you don't get data, it's because the configuration of your database might fail. So that's why you are not returning that data when you are running the GraphQL project. Make sure the two previous commands, let me get back to the guide. Make sure the dvmigrade and dvseedall worked by having this output. If you have a different output, let us know. Paste the output in the chat. So we will be able to help you with that issue. Okay. Thank you again Juan for all your help.

12. Running and Debugging the Application

Short description:

Now that we have our app running on debugging mode, let's keep it running on debugging mode. Let's start the Chrome inspect. Once you click on that OpenDedicated DevTools, there is an option to add different connections. So you might not have the localhost 9292. If it works for you, let us know. We can update the workshop. We will be adding the cross M option that Juan Buechner already shared with us. So definitely that's going to improve the workshop guide. But let us know if it works on Microsoft Edge because I personally don't know.

And Mo, it seems Rita having issues. If you can help them please. Awesome, let's continue. So now we know how to start the debugging mode. We started using the npm run, start debug. Let's make sure our application keeps working. If I execute the query, I'm getting information here and I'm getting the different console logs that we enable in our app with the stats of the different queries. Seems okay on the migrate and seed part.

Okay, seems okay. Check the psql. Oh, the PSQL command could not be located. Oh sorry. Let's install that. Just to confirm you have data. If it is at least running and you don't have data, don't you worry we will be able to debug the app and maybe take a look if the error is happening on the app or for some reason. I'm going to continue to the next section.

Now that we have our app running on debugging mode, let's keep it running on debugging mode. I also share some resources, how to get started with the Roku and Node.js if you have never used that there is a full guide. So you can go ahead and give it a ride. A read and the documentation around the debugger in Node.js. So let's continue with Chrome developer tools. Oh, somebody was missing a semi-colon. Right, missing a semi-colon. Oh, missing a semi-colon, SQL. You know, semi-colons are very important. Good, prune style Postgres. Okay, nice. Don't worry, Rita, that happens a lot. That happens a lot.

Let's start the Chrome inspect. So I'm going to open a new window. For this new window, I'm going to type chrome//inspect. Here, this is the remote debugging window from Chrome. From here, I can debug a bunch of different devices. You can see that my home has different devices that can be debugged right now. Well, the one we are interested is this link. The OpenDedicated DevTools for Node. So you are going to be clicking on OpenDedicated DevTools for Node. I know that you have these inspecting here but this will not work. Let's click on the OpenDedicated DevTools for Node. So once you click on that OpenDedicated DevTools, there is an option to add different connections. So you might not have the localhost 9292. I'm going to delete it to show you how to create it. So you're going to add a new connection and you're going to type localhost 9292. Why? Because, remember that in the package.json, we are listening on a different port. We specify the port 9292. Once we open the debugger, you are going to see a new message here that says debugger attached, and the debugger attached means that we have something that is already connected on the debugger portion of our app. Miko Mijos sounds better in Spanish. Technically I can work with this on Microsoft Edge, right? Since it's also now running on Chrome here or I am starting a war here between Chrome and Edge. As I say, I have not tested these on Windows and I have not used Edge. If these works with you, please let us know. Go on Edge, type Chrome colon slash, slash inspect. And if you see the same window, you are good to go. If you don't see the window, you will need to use Chrome. Right? If it works for you, let us know. We can update the workshop. We will be adding the cross M option that Juan Buechner already shared with us. So definitely that's going to improve the workshop guide. But let us know if it works on Microsoft Edge because I personally don't know. I don't use that. But if it works, please. Oh, nice. You got it. So it works. So go click on open dedicated tools for note. So you can use Microsoft Edge. Nice. That's good to know. Awesome. Okay, on the connections section, make sure you have localhost 9292.

13. Using the Debugger and Familiarizing with Panels

Short description:

In the debugger, you can navigate through different panels such as the console, sources, profiler, and memory. The console panel displays the output of your application and allows you to inspect objects. The sources panel is where you navigate your code and add breakpoints. The profiler panel is used for performance analysis, recording CPU profiles and analyzing memory usage. The memory panel allows you to take snapshots and analyze memory allocation. The guide recommends exploring the documentation for more in-depth knowledge. Next, there is an exercise to add a breakpoint on line 18 in server.js and familiarize yourself with the debugger controls. You can continue execution, step over or into function calls, and enable pause on exceptions. The debugger provides access to the local scope, call stack, synchronous stack trace, and global scope.

And I think that's on the instructions. Let me open the instructions. Yes, you need to have 9292. This is the node. By default, node inspector, we listen on 9229 but we will use 9292 to prevent any sort of conflicts. Right.

Okay, awesome, so it works. Then let's navigate on the four different panels we are going to be using. We have the console panel. The console panel is the one that pretty much has all of the output of our application. Here you can see the object that has that introspection query and list customers. This is the same console log that we have from here. It's the same one. If I send a new query, let me send a new query to the playground, get back to the debugger. Now we can see here that there is the new information. The SQL query and information in here. So we can use console to take a look at the output of our application.

Sources is going to be the main debugger window. From here, you can navigate to the files of the application that is already running. So here you can see the server.js file. You can see the order different folders with the other files with the resolvers, with the services, et cetera. So this is where you are going to navigate on your code and where you are going to start adding the breakpoints.

The other panel is the profiler. The profiler is where we are going to do the performance analysis of our application. We will record JavaScript CPU profiles and we'll analyze what those profiles looks like. Memory is where we are going to analyze our memory. From here, we will take a heap of snapshots, we will hone down memory leaks, we will be able to add the allocation timeline to see how many objects are being allocated on every request. So make sure to get familiar with these different panels. We are going to be working on these sources panel a lot. Let's continue with the guide, because I forgot what is next. So open dedicated dev tools, make sure you have the connection. Let's navigate to the different panels, the console, sources, profiler and memory. And there is some documentation for you if you wanna dig deeper. Cromp DevTools is a different whole world. It has a lot of tools for you to play with. Very, very recommended to take a look at the documentation if you wanna learn more. This is mostly backend debugging. I am not doing any performance review on the front end or any of those magic things that DevTools has, we are just working on the dedicated DevTools for Node.js.

Next, let's work on the exercise which is gonna be the debugger. Now, there is an exercise. Go to the source panel and add a breakpoint on line 18 in server.js and get used to the debugger controls. So, you have the screenshot in there. I'm going to be doing the same. Line 18, add breakpoint and nothing happens, let's send a request. We're going to be sending a request. And when I send the request, it pauses because I added a breakpoint by clicking on the line number on that file. And now I have stopped in here. So, what do we have in here? We have the navigation. Here, we can continue the execution. If I continue the execution, it's going to keep pausing because it will try to keep sending those introspection queries that automatically happens with GraphQL Playground. I can step over the next function call if I want to continue the execution of the project, I can step into the function call, for example, if I want to get into collect queries. What does collect queries, is doing, and I can keep playing with the different controls. Like pause on exceptions, very good if something happens, if there is an error that we are not catching up, we can enable dad, pause on caught and uncart exception. So, very good if you want to specifically debug, if there is an error or application. We have access to the scope here, so we have access to the local scope. The local scope of this context function, we are going to see that the local scope has access to the request object, which is the request we are receiving right now from the client, and the this object, which is the Apollo server object. So now, you can go deeper and analyze the different objects from here. And you have access to the call stack. So, you can see the call stack here, has the context, like the context function, has a function called process, takes and rejections. That's something that happens with the promises operation. But then, you have access to the synchronous stack trace. Remember that I told you that now these divockers support the synchronous stack trace? So, you can see what's going on inside the Apollo server file, all of the different functions that are being executed. You are identifying here Express information. Then, there is another asynchronous operation here, which is node.js.internals. Then, you have the HTTP incoming message, which is the request that is coming from the internals part of node.js. And you have access to everything that is happening on this specific function call. You also have access to the global scope. So here, you can see all of the different objects that are defined in the global scope, and you can navigate. Let's step into the next function call. So we have access to the collect queries function, and I think the guide tell us to do that.

14. Adding Log Points in Chrome DevTools

Short description:

To add a log point in Chrome DevTools, right-click on the line number and select 'add log point'. Specify the expression you want to log, such as the operation name from the request body. Lock points were added in Chrome 73 and can be used instead of breakpoints. If you already have a breakpoint, you can convert it to a lock point. After adding a lock point, you can see the logged information in the console panel. The lock point information includes the operation name of the request. You can continue the execution multiple times and see the lock point information in the console.

Let me see. Yeah, you analyze the content of the request, then navigate into the service collect queries function call. And here we are going to be adding a log point on line seven, by right clicking on the line number and select add log point, okay? And then we are going to add the following content. So you have everything on the guide, just copy and paste, or if you have your own code, your own project, make sure to add a expression that makes sense for the project you are debugging right now. Line seven, right click, add log point, paste the expression. The operation name is request body operation name. How do I know that? Because I have access to the request. I can take a look at the body and the body gives me the body shape. Like it contains the operation name, it contains the query and it also contains variables. So this is good for debugging what requests we are receiving on our application.

There is only add break point for me. Okay. What version of Chrome are you using? That's a very good question. You are going to find out... How can I know? About Google Chrome? Yeah about, click on that about. There you go. Yeah. I'm using the version 89. Seems like that. Up to date. Lock points. You have the same version, pretty much. Lock points are not that new. Chrome dev tools lock point. It's added on Chrome 73. So they're added on Chrome 73. So can find and then it can find log point Chrome dev tools. What? That's odd. Let me do something. I'm going to be opening Chromium. I just installed Chromium. I don't have anything on Chromium. So let me open the Dedicated DevTools for Node. Well, I already have it running. Let me let me configure it to connect to localhost 9292. Let me open the Dedicated. And let me see if I'm missing something. Services index at lockpoint. So it should be there. Oh, maybe if I already have a breakpoint. Oh, if I already have a breakpoint, I can add a lockpoint. Nice. Good to know. Oh, I was concerned. Yeah, no. Add a lockpoint, instead of a breakpoint. So remove the breakpoint by clicking on the line, and right-click, and add the lockpoint. Awesome. Thank you. Thank you very much, Mike. Please don't have a breakpoint in there, and add a lockpoint instead. You can have both. Good. Thank you for all your help. I'm closing Chromium so we can continue with Chrome. So now that I add the lockpoint, you can see it is of a different color. If I did the breakpoint, it will let me update the expression that we have in there. Go back to the console. Sorry. Let's continue the execution. Let's continue the execution multiple times, and go to the console. And now you are going to see the lockpoint information in there. Operation name is In Trospection Query. If I send another query, Least Customers, and continue the execution, here on this console, we are going to see the operation name is Least Customers. This is still, I'm going to remove this breakpoint and continue execution. Let's remove the breakpoint on line 18 so it doesn't mess with us. Let me see, what is the operation name is? Least Customers. Let's execute Least Customers. Now we have the operation name is Least Customers. OK, that's what I wanted to do.

15. Debugging with Breakpoints and CPU Profiling

Short description:

In this section, you will learn how to use the debugger effectively by adding breakpoints, lock points, and conditional breakpoints. You will also learn how to use watchers to monitor specific expressions. These features allow you to navigate and debug your code more efficiently. Additionally, you will learn how to record a CPU profile using the profiler panel and analyze the timeline of function executions. This will help you identify performance bottlenecks in your application.

Make sure that the lock point is being evaluated. Just remove the other breakpoints so it's not going to always stop in the same place. I think I already mentioned that in the guide. Maybe. OK. So you can continue playing with the debugger, add breakpoints in other parts of the application. For example, go to the GraphQL resolvers file, add a breakpoint on line nine, hit on the resolvers, add one on the line nine and execute list customers. And now it's going to stop under resolver. And now in the resolver, you can also go into the function call that's going into services again. And if you wanna debug the internals, you can go ahead and do it. And now you are working on the internals of node.js if you are having issues in there. So get used to the workflow, get used to the debugger, add break points here, add there, add lock points. The idea of this section is so you get used to the navigation.

Okay, let's continue the execution. Let's remove the breakpoints so we don't have any issue later. You can disable the break points by just like clicking on the checkbox in the breakpoints part. You can also have a Watcher. In here, if you wanna watch a specific expression, for example, the request, you can right-click that and add the selected text to the watches. There it is. What is the Watcher? Yep. And let's stop in there. And I think every time that it's going to stop there, you will take a look at the expression. For example, the REQ, request is not available because we are not pausing here. Now, if we add a breakpoint here, now the request is available on the watch, so I can take a look at the specific object I wanna review. These work with expressions. So let me, for example, I wanna take a look at the body, not bot, Julian. What you are typing, bat? So request that body. And body is an object. So that's a way to just isolate the different expressions that you wanna debug here. You can also have something called conditional breakpoints is just if an expression succeed or an expression happens, a stop. For example, stop if operation name is equals a list customers. That's conditional expression. So let me stop in here and to see if this is evaluated. We can see that the operation name is this customers. So this is why it is stopping here. But that's another way to add a breakpoint into your application by doing a conditional breakpoint. And it's just adding a JavaScript expression that is going to evaluate to true. And if it evaluates to true, that's going to stop in there. Very useful if you wanna develop a specific situation in your code. Yeah, that's very useful as well. You have like, even for long operations, for example, here, when you add a breakpoint, you can stop depending of where you want. So you cannot break points on different parts of your code. For example, if you wanna debug if the service says is null or not, so it doesn't evaluate the full expression. So it's getting way better, this debugger. Now that we've finalized, let me disable all of the different breakpoints because I don't wanna have issues later in the future. Let's continue the execution of our app, continue with the guide. What's next? Next is to learn how to record a CPU profile. So we are going to start taking a look at the CPU. Here is the documentation for you to take a look in the future. Now let's continue with the performance. So how to record a CPU profile. Go ahead and open the profiler console or the profiler panel. So let's go on the profiler panel. Make sure your project is running. Here server.js is running. And what we are going to do is start to record. Just do it for 10 seconds, send some traffic and stop. That's it. Just for some seconds. We are just going to take a look at the profiler. So what do we have here is a timeline of the function executions. So see, you have like some long lines around the 6 seconds. Let's zoom into this by using the mouse wheel. So I'm going to use the mouse wheel. If you don't have the mouse wheel, you can use the mouse to move these specific sliders. I'm using the mouse wheel to focus on these function execution. Let's open it. From here we can see what happens when a request comes in, in CPU. So we see that we have a known connection. So there is a connection that is being created, then a socket and the amount of time in CPU that that operation takes.

16. Analyzing Internal Events and Load Testing

Short description:

We are going to see some other events that are going to happen internally in Node.js. We will take a look at some express function calls, such as the CORS middleware and the JSON parser. We will also analyze the operations happening on specific requests, including process takes and rejections, GraphQL functions, and CPU performance. Additionally, we will explore load testing and profiling using Autocanon and the Visual Studio Code profiler. We will send traffic to our application and monitor the CPU load. Finally, we will discuss the difference between sending traffic to port 8080 and port 9292.

We are going to see some other events that are going to happen internally in Node.js. You have the URL which is the source file. Then you see that there are some headers that are being parsed. And then you are going to start taking a look at some express function calls. So the application, going to the different handles, going to some rotor handlers, going to middlewares, for example, the CORS middleware that our application have. The CORS, the JSON parser. So you can see all of the different operations that are happening on that specific request.

Here, for example, is the process takes and rejections. Remember when we were debugging the GraphQL part there were this operation process takes and rejections. Now we are going to take a look of the GraphQL things in here. Here, we have the context function, the collect queries function, the get queries stats and the console call. And remember that we have that console call. And I told you that console is a blocking operation. Here, you can see that it's taking 0.3 milliseconds which is not that much. But if you have a lot of information in here it might take more time. This is a good view of how much time in CPU your functions are taking. Here, we are taking a look at the list customers queries from the resolvers that are executing the find all function in the model then that find all function is doing a select a query and it's doing all of the different operations until that information is returned. So this is a very good way to view the operations in CPU.

If I go to other different execution, for example here is just receiving a new connection. Let me go to other operation in here there are some small operations and meeting events. Let me go to this one, what is this one? This is a very long one. This is the introspection one. So here is doing the introspection query is doing a lot of resolve operations from GraphQL. So you can see that, that introspection query might be a little bit expensive. So we might disable that, it's a small time. So if you have a function that is taking a lot of time you are going to see the wider the lining here the wider the function is taking CPU. So very good way to analyze performance issues.

Let's send some load into our application. So let's go to profiles. Let's continue with our guide. So here we are doing some load testing. So make sure you install Autocanon after you have AutoCanon we are going to execute this command. So what it does is opens two connections. It would send traffic for 10 seconds to w URL using the list customers query. So that's what it's doing. Sending a ton of different requests. So let's go to Visual Studio Code send some request without the Canon and we are going to see that this is going to take a bunch of time. So let's get ready. Let's open before executing the command let's get ready with the profiler, let's start the profiler, go to Visual Studio, send the different requests. Now you are seeing that I'm sending some unnamed request because these are anonymous queries, 318 requests we have sent. Go back to the devoger, stop the CPU profile. Let's wait a little bit because now it have more information. Oh, I haven't stopped. What I did? Okay, now it is stopped. And now you can see that now the CPU has way more load because we submitted a bunch of different requests. If you start zooming in to each one, now you can identify the same request for being sent multiple times. So there is a still a lot of little time between requests, pretty much 30 milliseconds. You can start increasing those numbers to see if you can get a different view. That's a very good question, Mike. Why send to 8080 but not to 9292? 8080 is where my application is running, 9292 is the debugging protocol. So 9292 is for the debugger to connect and start talking on that debugging protocol, the V8 inspector protocol. 8080 is my web application. So when you start on debugging mode, let me go to Visual Studio code and show you. When you start on the debugging mode, it will listen on a WebSocket on 9292. Chrome developer tools and Visual Studio code is going to use WebSockets and the V8 inspector protocol to communicate with the debugger. And my application is running on the 8080. I am sending traffic to my app and monitoring the CPU from the debugger. So this is why I'm sending traffic to my app. I don't want to load the debugger. I wanna load my application. Okay, let's tweak it a little bit. Let's send more requests to see if we can change this graph. Let's start a new recording. Let's tweak the command. So let me say 10 connections for 10 seconds. So I'm sending way more traffic, way more concurrent traffic. Don't add a huge number in here because it might it might occupy all of your different file what's the name of this? Sockets or file descriptors in your app. Sorry I forgot the name. If we locate by your file descriptors in your app if you add 100 concurrent connections, it might be too much. You don't want to block your computer.

17. Analyzing Memory and Hunting Leaks

Short description:

To identify performance issues, we analyze the operations performed by each request. The application has good performance, with an average latency of 120-130 milliseconds and an average of 80 requests per second. Now let's move on to memory and hunting memory leaks. A memory leak occurs when objects are retained in memory even after a garbage collection cycle. We will use tools like CAPTURE heap Snapshots and the allocation instrumental timeline to identify memory leaks. First, we need a baseline snapshot of the application's memory. Then, we send traffic to the application, trigger the garbage collector, and take additional snapshots. By comparing the snapshots, we can determine if there is a memory leak. Let's continue with this process and take another snapshot.

You don't want to create a very huge profile. If you want to do like a huge load test in your application, it is better to run those commands from an EC2 instance in AWS or a different server that is going to be remote. So it doesn't load your local computer. And if you can see here right now, I submitted way more traffic and now these graph looks a little bit wider. The space between requests is shorter because I am sending more and you can keep playing with this. But what is important here is to take a look at one request all of the different operations that it does. So these are all of the different operations that are doing it one request and very useful to identify performance issues in your application. So far, this looks pretty good. Your application or this application have very good performance. We can take a look at the output of AutoCanon. It is letting us the latency. So the latency is around 120, 130 milliseconds is the average. It's a very good latency. We had some percentiles that are returning more than a second. Maybe it's doing something crazy in there. All in all the application looks good and it's returning all of the different requests are successful and it's doing an average of 80 requests per second. So our application is performing well Let's continue with memory. So we wanna learn about memory. So let me stop the process. Start again because we want to start with fresh memory in our application. This is a specifically useful when hunting down for memory leaks. So I'm going to be explaining you what is that in a moment. And let me go to the guide. Continue with memory. Hunting memory leaks. So a memory leak is when your application is allocating objects in memory, it's retaining those objects even after a garbage collection cycle has happened. Some objects are released after a garbage collection but is there something that is retaining those objects or they are holding on those objects, all those objects are not going to be cleaned by the virtual machine, by the, sorry, by the JavaScript engine, by V8. So if you keep holding onto objects it might keep increasing the heap and sometimes you are going to reach a limit and your application is going to crash. So Mike says, profiling is always hard. Now we know how to record. Maybe next time do a workshop about how to fix the profile problem. Right now, we don't have a profile problem. We might be able to introduce one but I am having a memory leak that we might fix. I'm going to tell you how but let's identify the memory leak first. First. So there are like two very useful tools. I'm going to be showing you the first one which is CAPTURE heap Snapshots and comparing heap Snapshots. The other one is taking a look at the allocation instrumental timeline to see how many objects are allocated per request other workshop of course, we need to do way more workshops in the future. So let's continue with this. So our application is running on the debugging mode. We are on the dedicated DevTools for Node.js. We are on the memory panel and before starting, we need to have a baseline. How our application looks like when there is no memory when your application have started. So let's click on this Garbash to trigger the Garbage Collector. After we trigger the Garbage Collector, let's take a snapshot. So this is going to take a picture of your currently allocated memory. And from here you can take a look at some strings that your application have allocated. These are a lot of modules, some arrays, closures, different objects that your application has. So you can see some GraphQL information in here. This is how your application looks like from the beginning. So they are like the different GraphQL types in here. Some GraphQL input object. I think this is the customary input object if I am not wrong. These are all of the different objects in memory. What we're doing is load the application, send a bunch of traffic and take another snapshot. So we are going to profiles. Let's go to our workshop guide, send a bunch of traffic for 30 seconds. Wait, so you can do this on your own. Wait 30 seconds, we are sending a bunch of traffic. After we send the traffic, we are going to take another is Snapchat. The recommended way is to wait some time until we let JavaScript trigger the garbage collector and then send more traffic. And capture another is Snapchat. Wait some time, send more traffic, capture another is Snapchat. Rinse and repeat for five times. I think with five different is Snapchats, we might have enough to see if we have a memory leak. So we send a bunch of traffic to our app. Now it is time, oh, this is confusing me. Let me close Chromium. Now it is easier. Now let's take another Snapchat.

18. Analyzing Memory Usage and Investigating Leaks

Short description:

The memory usage of our application keeps increasing, indicating a memory leak. We have tried increasing traffic and analyzing the memory snapshots, but the memory usage remains high. Comparing snapshots has revealed that certain objects, such as compile code and system code, are still retained. Additionally, we have encountered some timeouts in the application. We are currently investigating the issue and would appreciate any input from the participants.

And we can see that from 17, we have 20 megabytes. So there are like more objects. That is expected, our application has received traffic. Let's see is that, if that number keeps increasing. Send more traffic. So we are sending another 30 seconds of traffic. Five people are crazy leasing customers on our application. Let's see if we can increase memory somehow. Waiting some time, on the meantime, you can do the same thing on your own project. Send traffic, take a Snapchats and to see if you get the same results as me. Let me know if you find something different. Let's take another Snapchat. I have from 20 to 21, one megabyte of information. Let's send more and let's rinse and repeat. Four, five Snapchats is what we need to see if there is some memory leak in our application. We don't want to see that, but for this workshop or for the purposes of this workshop, we might want to see that number increasing not to crazy because the memory leak is not a big but it is a still a memory leak. So let me add more, maybe increase connection cause memory leaks. Maybe we can send more. Let me record another one, 21.8. Let me do the next one crazier. Let's say 15 people in 30 seconds. Oh no, my CPU is going high. Let's go, nothing crazy happens. Now I have 15 connections sending more requests to my application, so something might be happening. Show me the output. Whoa, look at that. Now I have like 8,000 queries or more that has been executed on my application but this is holding up. The application is still alive. Let's take another Snapchat and I think we are ready to finalize. 22 megabytes, definitely a memory leak. This is not going down. We are still holding up into objects. Let's do a manual garbage collector and trigger a new snapshot. Ah, it didn't release too much. I mean, we are still having high memory, higher than the baseline. So what we are going to do is comparing the last one with the previous one to see what objects has been retained. We can do, for example, with the Snapchat 3, compare what objects are still in there that has been allocated between the Snapchats 1 and 2. So we can see that we have some objects that are still retained on a Snapchat 3. So we can see, for example, compile code and system code are expected or arrays are, we, for some reason, contain, retaining some arrays. Let's take a look at the array section. Open this. Why this is not opening? Oh, okay, it's opening. My AutoCAD on call results into the following. 15 error. So no requests are sent for some reason. Do you have any output in your application? Alex say. Maybe on the console or paste the full AutoCAD on command to see if there might be an error. Paste it on the chat so we can take a look. Yeah, sometimes maybe the request is not sending the right information. Let me review. On the meantime, while people are working, I'm going to review Alex's output. It seems... Let's... It seems good. Let me try to execute your same command. Is your application running? Just, or 15 errors, 15 timeouts. Oh, no, just, they're just timeouts. All of them are timeouts. Maybe some of them has not been received. Cool. Can you take a look more, maybe I'm not able to copy and paste from Windows to the Mac right now. But it seems something might be happening in there. If anybody else is having the same issue, please let us know on the chat so we can take a look. But let's continue reviewing the memory. Here I have the array. Let's take a look, for example internal array. No, this is retaining like 26K. Information, we have some object properties in here. If I click on object properties, we are seeing some info in here. More object properties.

19. Analyzing Memory Leaks and Replicating the Issue

Short description:

We identified a memory leak, but surprisingly, we managed to fix it without even trying. We used allocation instrumentation timeline to track object allocation on each request and discovered a segmentation fault that caused the app to crash. We replicated the issue and took snapshots to analyze the memory problem. The workshop is focused on Chrome developer tools, where we explore different features and techniques to debug Node.js applications.

We can see that we are retaining some information. Let's go to the last one, the Snapchat 5, and filter between Snapchat 4 and 5, between the previous and the current. Here we are seeing that most of the retained information are going to be arrays. If we open the arrays, we can explore. And I'm getting different results. That's awesome. I'm not getting the results I was expecting. I'm taking a look at objects. I'm seeing that I have a bunch of different objects. These are going to be connections. But for some reason, I'm not getting the exact information from the memory leak. Huh, nice. So what I'm doing wrong? Did I fix the issue? Maybe? I don't think so. The strings. I'm having a bunch of logs also. Why am I retaining that in memory? So hunting down a memory leak is a detective-like operation. Detective-like operation? I am not getting the results I was expecting. I should have seen a bunch of information from the query stats, but for some reason, the query stats are not appearing in this code. So nice. I am not able to replicate my issue. We fixed the memory leak without even trying. So let me clear all of the different memory profiles. I'm going to do an allocation instrumentation timeline. This is going to create a timeline and show what objects are being allocated on each request. So I'm going to send some traffic. I might have the same issue. Let's send some traffic, take a look at the timeline, stop recording, and analyze what objects are being allocated on each request. Let's wait until it finalizes. It seems I had an issue. Oh! This is why my application reached a segmentation fault. We crashed the app. This is why this is not working. So let me try to replicate this again because I want to hunt down the memory leak, definitely. So debugger, attach. Trigger, heap snapshot. No, no, no, no, no. I don't need the timeline. I need the other snapshot. So delete, go to profiles, heap snapshot, take snapshot. This is the first one. Send traffic. I'm not going to send that much. Maybe we killed the application? I'm not going to send the one request I had prepared with just five connections. So sorry, sorry, Mike, your suggestion really killed the app with a segmentation fault. So let me try again just with five connections, 30 seconds, and I'm going to take some snapshots to see if we can look at the memory issue. If not, there is a screenshot of the one I took while preparing the workshop. But the idea is to see if we can replicate it. Okay. We send traffic, take a new snapshot. We might be seeing that the memory is increasing. Yes. Take another one, take another snapshot, and see if we can identify the objects with just three or four snapshots. Because it seems we are past the time, but we started a little bit late, and we already have a little bit of content to give, which is not that much, but the main portion of the workshop is in the Chrome developer tools. Yeah, exactly. We are consuming all of the different file descriptors on the local machine. Okay, doing another snapshot, let's hope it works. Now we have 4,000 requests. Okay. And the last one. The last one. Send more requests and see if we can identify where we are leaking memory. That's another set of requests. 30 seconds, 5 concurrent connections. Now, we have more than 6,000 objects. Finalize, finalize, finalize. Awesome! Let me take a look.

20. Memory Leak and Data Storage

Short description:

We have identified a memory leak in the QueryStats object, which is being retained in memory along with a large number of HTTP connections. To fix this, we recommend extracting only the necessary data from the request object and finding alternative ways to store and track the stats, such as using Redis or other databases. Keeping global objects with constantly growing data can lead to memory overflow and application crashes.

Now, we have more than 6,000 objects. Finalize, finalize, finalize. Awesome! Let me take a look. Another snapshot. Take some time. Let's hope it doesn't crouch. Let me know if you're having that issue. OK. It's finalized. Yes, definitely a lot of memory. Now, selecting the last snapshot, going to the filter, see the objects allocated between the 3 and 4. And now, we are taking a look that we have a lot of different arrays that are being retained. Take a look at arrays. We have object elements. And this is what I wanted to see. We have some object elements of an array that is called Query Stats. Query Stats lives in the context of this function call, call GetQueryStats. So we know that these object QueryStats exist within this context. And from here, if we open this, we are seeing a lot of different objects that are being retained. So this is what we are, that we might want to look, are objects that are still retained in memory. So we have also a lot of Promise IDs. We have some Promise operations that are being retained. They might be related with the same memory leak that we have. These other ones are part of the HTTP operation and connection, which doesn't seem to be retaining a bunch of memory. But if you see the one that is retaining a lot of memory is the first one, these QueryStats one. We can take a look at objects as well, and if we see objects, we are seeing a bunch of connections. So we are retaining a lot of different HTTP connections, and that is not good. So we have a lot of different HTTP connections that are being retained in memory. What else? We have some strings. And if we see the strings are the strings from console log, we can take a look at all of the different strings. This is pretty much from the console log, so we are seeing that that is also retaining some memory, but not too much. This is not killing our application. So pretty much from the first one, from the array that is retaining 80K in memory, we are going to see that queryStats is the one that has the issue. When we click on this index.js file, now we know that queryStats object, which is in the same context of the getQueryStats function call, in the function guide in the workshop guide, it is different. Well, I was hunting down the memory here. I also find the queryStats as being a problematic object, but it was within the context of the leastCustomers function. So the results might be different, but it will show you some places where to look where you might be having a memory leak. So what we are seeing here is that we have a global array that is storing the body of every request. So here we have two problems. Here, we have the full request object retained in this function just to get the body and store the body in an array. So one way to fix these memory leak or not to make it that bad at least for not being retaining the request objects is to just extract the body. So if I just extract the body from the request I am not retaining into the full request object. I am just getting the body without retaining the full request, but I am still adding objects into the QueryStats global array. And this is going to grow until I have a way more objects and requests in my application. Sometimes these applications are going to be destroyed, killed. The other way is to fix these two functions. Collect Queries and GetQueryStats, right now, what I'm doing is a reduce operation over an array to be able to count the number of queries by operation name. This is kind of clever-ish, but not very clever. My recommendation is to get rid of this and instead keeping track of the stats in a different way. For example, using Redis, you can easily have counters in Redis that are not going to be using memory from your application, but they are going to be using a NoSQL database that is going to be made for this specific purpose, and that way we are not going to be having this memory leak, or store this information in another place. You can use Postgres if you want, or you can use etcd, or other different databases to store that information. Don't keep global objects with data that is going to be growing constantly in time because at the end is going to bite you and fill out your memory and your application will crash.

21. Debugging with Visual Studio Code

Short description:

Don't keep global objects with constantly growing data, as it will consume memory and crash your application. Visual Studio Code provides a debugging panel and pre-configured options for Node.js debugging. You can add breakpoints, view variables and call stacks, and use step-by-step debugging. Visual Studio Code does not have memory and profiler features, but it supports lockpoints. Remote debugging is not recommended due to security risks. If you need to debug remotely, use an SSH tunnel for a secure connection.

Don't keep global objects with data that is going to be growing constantly in time because at the end is going to bite you and fill out your memory and your application will crash. Okay. So that was the memory section. You have all of the guide and information in here and some resources that are going to be super useful, how to fix memory problems using Cron Developer tools, and learn a little bit more about memory management and garbage collection from JavaScript on the Mozilla Developer Network documentation, and a very good article from my friends at Nodesource, Memory Leaks The Mistified. It will tell you everything about memory leaks, how to identify them and some other tools that are going to be useful to hunt down these memory leaks.

Next, I'm going to be passing these very, very quick because we are out of time, how to debug on Visual Studio Code. If you are using Visual Studio Code, it's going to be quite simple in this case. Visual Studio Code makes debugging simple by having a debugging panel into the code editor, by having already configurations for Node.js. So pretty much, let me open the Chrome Developer Tools, stop this process. So you have different ways to start debugging. There is a debugging panel that you are going to find on the left paneling in Chrome DevTools. From here, I already have a configuration. Can I delete it? Yeah, I already have a configuration. So let me go ahead and delete that configuration. So it shows me how it looks like from scratch. Okay, I don't have a configuration yet. I have a brand new Node.js project. So it gives me the option to create a launch JSON file if I wanna customize the configuration, like I mentioned before, the Visual Studio Code have a lot of ways to customize the debugging configuration. Or you can directly run and debug this application. If I click Run and Debug, it will give me different environments where I wanna debug my application. I wanna use the Node.js Debugger, not the legacy, the Node.js one. I click on Node.js, and that's it. Is running, the GraphQL server, on debugging mode, and from here, I can add a breakpoint. So I can click on the line number, add a breakpoint, and if I execute that query, it's going to stop. And we have the same, we have variables here. I can take a look at the body. I can take a look at the global variables as well. I have access to the call stack. So I can see the call stack and asynchronous call stack, similar to what we have on Chrome developer tools. I can pause on cut and on cut exceptions if I want to debug on any specific, on any specific exception that my application have. I can use the step-by-step debugger, stepping to function calls, and make sure that I am debugging properly. What we are not having here is memory and profiler. We don't have that in Visual Studio Code. It also support lockpoints. So you can go ahead and right-click at a lock point and it will use the same structure that we were using on Visual Studio Code. For example, stats are, getQueryStats. This is a way we can add a lockpoint in here and we can keep playing. And now you can see that the information is going to be output on the terminal as well. And from here I can stop debugging my application. Useful, simple. You will not need to get out of your IDE if you wanna debug applications. Let me go ahead and take a look at the chat. Thank you everybody for joining. I am going to be finalizing the content if you wanna stay or you can finalize it by on your own, the content is already there. Juan Sebastian asks, can you repeat why the retainer of the request was a problem is one of the problems. So why? Because that function has a hold on the request object just to get the body and I am not releasing that object. So pretty much I am also leaking request objects in my application in there. If I just send the body option without the full request object, I just need just the body for the operation I am doing. I'm just storing bodies into that array. I'm not storing the request information. So if I just need the body, just pass the body into the function. Don't pass the full object. That's a way to avoid holding on to objects into function calls. Okay. Perfect. I wasn't paying attention to this chat because I am in two computers right now. Let's continue with the workshop guide. There is information, how to debug node.js application with Visual Studio. All of the different information about the customization that you can do with the different configuration files and configuration attributes. Go take a look. If Visual Studio Code is going to be your main tool for developing applications. Remote debugging. The first rule of remote debugging is don't. Don't do it. It's very dangerous because you are exposing your full application to people. If you are going to do remote debugging, don't enable that debugging port to the public. Running privately and use something like an SSH tunnel to only connect to that port as if it were a local connection. That way, only you that have access to the server via SSH are we'll be able to debug your application. Don't open that port to the public because people can start debugging your application, changing the code and doing crazy and malicious things with your code. So, caution, don't do these unless you know what you're doing.

22. Remote Debugging on Heroku and Docker

Short description:

To enable remote debugging for Heroku, start by changing the proc file in your project and adding the 'start debug' line. Commit and deploy the application to Heroku. Create an SSH tunnel using the Heroku CLI command 'Heroku PS forward'. Open the dedicated devtools and start debugging your application remotely. Dockerize your Node.js application using the provided commands to build the image and start it in debug mode. Expose the necessary ports and use Chrome Developer Tools to debug the application running on Docker. Install the debug module as a dependency and modify the GetQueryStats function in your code.

Always create an SSH tunnel if you wanna do remote debugging on your application. The Heroku makes this process very easily and simpler for you. So let's take a look how can you enable remote debugging for Heroku. So on our project, first, we are going to be changing the proc file. The proc file. Let me go to the terminal. Also, let me open the project. The proc file is where you specify what command is going to be executed for your project. You might have here npm run start or node server. I think that is the default that you have in there. Make sure you have this line. Here on the proc file, we are going to start the debugging mode on Heroku. It's going to be safe because Heroku doesn't expose that port. Any port that you open in Heroku is only going to be the 80 or the 443. The web port or the SSL port, you don't have access to any other port on Heroku. So if you open these on Heroku, nothing is going to happen. So make sure the proc file have these start debug. Then add the proc file and create a new commit. I already did that. So I already created this commit, but it is not on the remote branch. So you will need to do these two steps and last deploy the application to Heroku. I need to deploy it. So I'm going to do git push Heroku main. So git push Heroku main is going to deploy my application to Heroku. Is going to build a new container image and is going to start the application in debugging mode. But I don't have access to the debugging that application yet. I will need to create an SSH tunnel. But since I don't have SSH access to Heroku directly, I don't have credentials, I don't have a key. The Heroku CLI already gives me a way to easily create a tunnel from Heroku to my computer. So how to create that tunnel by running the Heroku PS forward. PS means process forward, is going to forward a port from Heroku to my local computer. Make sure you are not on a VPN because some VPNs might decline this tunnel. So I'm going to be copying this line, Heroku PS forward, pasting the line on my computer. Running this command for the first time requires a Dyno restart so my application is going to be restarted so I can have access to the SSH tunnel. It waits for application to restart. Let me wait. And establishing the connection and now I am listening locally on the port 9292. Okay? So I can go ahead, open the dedicated devtools. And if I go to the file, I am on a different folder. I am on appserver.js. This is the remote file in Heroku. So if I go ahead and enable the breakpoint and go to not the local computer, but my URL for my application, I am now debugging my application remotely that it's running on Heroku. So this is a very good way if I wanted to connect to a remote process in Heroku. It will also work if you are running on AWS or other service that supports an SSH tunnel, but the main message here is that Heroku makes it super simple for you. It's just one command to redirect the port into your local computer, and now you are connected and you will be able to start debugging your application locally that is running on Heroku. Awesome! Last, but not least, not last, but let's continue, I have two other sections and sorry I'm a little bit running because it's too late. I haven't spent that much time explaining this, but you have everything, everything documented here. Next is going to be Docker. Docker, if you have Docker, I provided two different commands. The first command is to build the Docker image, so let's build the Docker image from the same Application folder. I'm creating an image called DevOps.js, GraphQL rent API. Now my node.js project is built, this project already have a Docker file. So you can see how can you dockerize an Node.js application. And I am also providing in the guide our documentation for you. So you have access to an article. So you can dockerize your own Node apps. Then I'm providing the command for you to start that application in debugging mode. Two things to take into account for this command is that I'm forwarding both ports, the 92 and the 8080. And then I am executing the start debug in Docker. So I'm enabling the buggy mode in Docker and I'm exposing that port locally. I run Docker, and I can go now directly to my Chrome Developer Tools, open the dedicated dev tools. And this is an application that is not running on Heroku but running on Docker. And from here it is the same. If I go and open the local one, local host 8080, I send a request, it will stop eventually in the breakpoint. So that way you can debug an application that is running on Docker, just by exposing the port and making sure you are running or executing the application in debug mode. We have the examples, go ahead, play with those. And last but not least, the last thing that I wanted to show you is the debug module to do log in. So to enable this debug module on our application, let's install the debug as a dependency. Awesome, and let's modify the GetQueryStats function. So let's go to the code.

23. Debugging with the 'services' Namespace

Short description:

We require and execute the debug function with the 'services' namespace, replacing console logs with the debug module. By enabling the debug flag and executing npm start, we can see colored output from the debug module. The namespace determines which debug information is displayed. We appreciate your participation and invite you to follow us on Twitter. Feel free to reach out with any questions after the workshop. Thank you for joining us and we hope you had a great time. We will be uploading content to our Salesforce Developers Channel and welcome your feedback. Have a wonderful weekend and see you next time!

I am super fast because we are out of time, sorry for the people that it's in Philippines and it's like two in the morning. And let's modify the first lines. What we did is we are requiring debug and then executing debug as a function with a namespace. The namespace is going to be services. And then we are replacing the console log. Instead of the console log, we are going to be using the debug, okay? So remove the log points, remove this. Awesome. What are we doing is that? We are going to be running npm start but with the debug flag enable. So we are the debugging with, sorry, the debug environment variable enabled with the services namespace. Once we execute npm start, oh, I have something running. And I think I give you instructions, how to prevent this. So we have a docker container running and we will need to stop that docker container. I provided the instructions so you don't miss this while running the workshop on your own. Now I can do npm start with the services namespace enabled. Oh, I need to save the file. If I don't save the file, nothing happens. Now that I saved the file and I send requests, now you can see that I have a colored output that it's coming from the debug module. Since I enabled the namespace, I'm getting that information. But if I don't enable that namespace, now the output is ignored. I don't have any debug information. What if I execute debug asterisk? I can enable all of the different namespaces. And now you are seeing debugging information from Express, from SQLite and also from my own namespace.

And that's all we had for today. Thank you very much for joining us, joining me and Mohit on this workshop. You are the best. And you can follow us on Twitter. My Twitter is Julian underscore Duke and Mohit is MsRibasta13. Please follow us, my DMs are open. If you have any questions after the workshop, you can drop me a line in there. I will be still monitoring this course at me as a friend of this course. I use this core a lot because I am a dungeon master and I run a lot of dungeons and dragons games. So this could've my other social networks so feel free to text me. If you have any questions after this workshop, this content is all for you. I hope you learn. I hope you like it and I hope you had a lot of fun. Thank you. Thank you very, very much. You are the best audience we ever had. Mohit, do you have any last thing to say? Yeah, there is a last question that I just picked up. So the question is from Alexi. He says, does Heroku have a command to tear down the application and database add ons to not unnecessarily spend the free time in minutes? I think, yes, we have that app delete command if I'm not wrong. Holy on. Yeah, everything is easy there. And we will be working on some content that we will be also uploading on our Salesforce Developers Channel. We will turn this into a series of short videos, so it's going to be more easy to consume. Please give us feedback, we also love feedback. If we did anything wrong, if something was not clear, if we did something bad, please let us know. We are always looking forward to improve. Thank you for your time. And I hope you had a very good weekend. It is Easter for some Catholic and Christian people. Other places you are going to have like some vacation, it is the weekend, enjoy, and see you on the next opportunity. Thank you. Thank you. Thank you so much for joining us. And until the next one, bye-bye. And I think I need to do something with this Zoom. I have instructions. Stop recording. Yeah, stop recording.

Watch more workshops on topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
Node Congress 2023Node Congress 2023
109 min
Node.js Masterclass
Workshop
Have you ever struggled with designing and structuring your Node.js applications? Building applications that are well organised, testable and extendable is not always easy. It can often turn out to be a lot more complicated than you expect it to be. In this live event Matteo will show you how he builds Node.js applications from scratch. You’ll learn how he approaches application design, and the philosophies that he applies to create modular, maintainable and effective applications.

Level: intermediate
Node Congress 2023Node Congress 2023
63 min
0 to Auth in an Hour Using NodeJS SDK
WorkshopFree
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool.
We will enhance a full-stack JS application (Node.JS backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session for subsequent client requests, validating / refreshing sessions
At the end of the workshop, we will also touch on another approach to code authentication using frontend Descope Flows (drag-and-drop workflows), while keeping only session validation in the backend. With this, we will also show how easy it is to enable biometrics and other passwordless authentication methods.
Table of contents- A quick intro to core authentication concepts- Coding- Why passwordless matters
Prerequisites- IDE for your choice- Node 18 or higher
JSNation 2023JSNation 2023
104 min
Build and Deploy a Backend With Fastify & Platformatic
WorkshopFree
Platformatic allows you to rapidly develop GraphQL and REST APIs with minimal effort. The best part is that it also allows you to unleash the full potential of Node.js and Fastify whenever you need to. You can fully customise a Platformatic application by writing your own additional features and plugins. In the workshop, we’ll cover both our Open Source modules and our Cloud offering:- Platformatic OSS (open-source software) — Tools and libraries for rapidly building robust applications with Node.js (https://oss.platformatic.dev/).- Platformatic Cloud (currently in beta) — Our hosting platform that includes features such as preview apps, built-in metrics and integration with your Git flow (https://platformatic.dev/). 
In this workshop you'll learn how to develop APIs with Fastify and deploy them to the Platformatic Cloud.
React Advanced Conference 2023React Advanced Conference 2023
148 min
React Performance Debugging
Workshop
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
JSNation Live 2021JSNation Live 2021
156 min
Building a Hyper Fast Web Server with Deno
WorkshopFree
Deno 1.9 introduced a new web server API that takes advantage of Hyper, a fast and correct HTTP implementation for Rust. Using this API instead of the std/http implementation increases performance and provides support for HTTP2. In this workshop, learn how to create a web server utilizing Hyper under the hood and boost the performance for your web apps.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

JSNation 2023JSNation 2023
29 min
Modern Web Debugging
Few developers enjoy debugging, and debugging can be complex for modern web apps because of the multiple frameworks, languages, and libraries used. But, developer tools have come a long way in making the process easier. In this talk, Jecelyn will dig into the modern state of debugging, improvements in DevTools, and how you can use them to reliably debug your apps.
React Summit 2023React Summit 2023
24 min
Debugging JS
As developers, we spend much of our time debugging apps - often code we didn't even write. Sadly, few developers have ever been taught how to approach debugging - it's something most of us learn through painful experience.  The good news is you _can_ learn how to debug effectively, and there's several key techniques and tools you can use for debugging JS and React apps.
Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Do you know what’s really going on in your node_modules folder? Software supply chain attacks have exploded over the past 12 months and they’re only accelerating in 2022 and beyond. We’ll dive into examples of recent supply chain attacks and what concrete steps you can take to protect your team from this emerging threat.
You can check the slides for Feross' talk here.
React Advanced Conference 2021React Advanced Conference 2021
19 min
Automating All the Code & Testing Things with GitHub Actions
Top Content
Code tasks like linting and testing are critical pieces of a developer’s workflow that help keep us sane like preventing syntax or style issues and hardening our core business logic. We’ll talk about how we can use GitHub Actions to automate these tasks and help keep our projects running smoothly.
DevOps.js Conf 2022DevOps.js Conf 2022
33 min
Fine-tuning DevOps for People over Perfection
Demand for DevOps has increased in recent years as more organizations adopt cloud native technologies. Complexity has also increased and a "zero to hero" mentality leaves many people chasing perfection and FOMO. This session focusses instead on why maybe we shouldn't adopt a technology practice and how sometimes teams can achieve the same results prioritizing people over ops automation & controls. Let's look at amounts of and fine-tuning everything as code, pull requests, DevSecOps, Monitoring and more to prioritize developer well-being over optimization perfection. It can be a valid decision to deploy less and sleep better. And finally we'll examine how manual practice and discipline can be the key to superb products and experiences.