 Okay. Hello everyone. Welcome to our tech talk. We are starting right now. So I will be starting with just a very brief introduction. Then I'll handle talking to Kate, which is joining us for this tech talk. And at the end of the session, we will open a few minutes to take questions from the audience. If you have any dull questions for any of us, you can either write them down or you can anticipate them on the chat box or the Q&A box of the Zoom platform. And we will address those questions at the end of the talk. Okay. So the title of our talk today's talk is serverless debugging with VS Code and AWS SEM. Just a little bit about ourselves. So Kate, which is already connected to us, he's a developer advocate, developer relations specialist. He has more than 12 years of experience working with serverless. And he's also specialized in mobile interfaces. And apart from that, he's also a writer in a developer relations consultant. My name is Renato. I'm a developer advocate at Dashboard. I've experienced building serverless backend systems for various large-scale services from data mining to machine learning, for example. We are connected to the two supporters of the today's tech talk. So the first one is Dashboard. It's a serverless monitoring and debugging platform. It is designed, especially for serverless backends. So it provides algorithms for automated call detection. It allows to set up some performance policies and receive alerts in real-time by email or Slack whenever things go south in your backend. It also integrates with X-Ray for tracing your applications. And it has a ton more features. So head to dashboard.io after this talk and register for the account. You are also available at Dashboard.io at the Dashboard handle. And also Moesif is an API instrumentation and analytics platform. So it provides out-of-the-box analytics for web APIs. It tracks API user behavior and also comes bundled with a smart voting system. It is compatible with all modern API standards flavors. So whatever is your flavor, whether it's REST, GraphQL, or anything else, Moesif is your API partner. You can find them on Moesif.com and Moesif HQ handle on Twitter. So after the talk, please head to Dashboard and Moesif website for Twitter accounts and please thank them for supporting this tech update. For today's talk, we will be covering how to debug as well as applications locally with Visual Studio Code and AWS SAM, how to automate Visual Studio for one-click debugging, and how to instrumentate your debugger from within your own code. We also have a repository. It's on GitHub.com slash K dash IS slash debug dash lambda dash BS code. So everything we are going to present here today will be available at these, inside this record as well. So go ahead and bookmark it or if you need, we're going to send these presentation by email along with the recording later as well. So you can check this URL later. All right. So I will head to K now. It's okay. If you turn on your mic, share your screen, please. Yes. Hello, everyone. Welcome to this webinar. Yeah, I'm K and I'm going to show you about debugging with Visual Studio Code and AWS SAM CLI. What we will do is we will start with a simple basic SAM CLI project and then introduce an error and try to debug it. And later I will show you how to set up Visual Studio Code so the debugging gets easier. And you don't have to run five things before everything gets running. I created this repository that covers most of the stuff we are doing here. It has some useful links at the bottom. The original article I wrote formative if you would like to read about it. So what we need, what I already have installed is Docker because the AWS SAM CLI will run your AWS Lambda function inside the Docker container on your system. It will use the AWS CLI in the background and of course you need an AWS account and Visual Studio Code. These are the things I have already installed and I will start from basic SAM in it so we get a project, a SAM project with the hello world function and that is written for the Node.js version 10 runtime. The SAM init command just creates a project with the hello world function and it does this with a, like I said, with a JavaScript runtime and it already tells us that we can use this command to invoke the function locally. So if everything worked correctly, this command should give us some output and not error. So I'm going into the project I created and I'm using this command that it suggested me which by the way won't work out of the box because they forgot to update their documentation. They say I can use the event, the example event in the root folder of my project but they pushed all the events inside the events folder. So if I run this, I will get an error but I will do this just for show you. So I got this error because the event isn't in the root folder. It's actually in an events folder. So this tries to run the function locally inside the Docker container. It uses a specifically created Docker image created by AWS for this. Chose how long everything run and how much memory it used and everything and the output of everything here. So everything is set up and worked and we can run code locally. So now I will start Visual Studio Code in this folder. So we can see, I'll get some errors here. Save. So it had a previous version in the cache from my last test of this talk. So it has created this project for us, the SAM project and we can run it. So now the next step would be to introduce some kind of error inside our function. Here we have the had a world function inside the app.js. And one kind of error that always happens or that often happens is people are sending you wrong events from your API gateway or something. So this event, the event we got from here, it's rather big, but can understand your path parameters or query string parameters, stuff we know from our HTTP APIs. And now here we get a query string parameter called foo that has the value bar. And let's say we would like to use this parameter in some kind of way. So we could do anything with our API. We get some stuff from our clients and we want to use it in our API. So, and we get this by extracting it from our event. It was called foo, I think, event. And it's inside our query string parameters. So now we can use the foo parameter in some kind of way, like here, for example, use a message, use hello plus foo. We would save this. And now the content of this foo parameter, the bar, should be added to the hello string that is our message we get back. Let's use the terminal for this and run the command. Like we did before, we use the sam local invoke hello world function. This is defined in the template, yaml, the sam template. It's called the hello world function. And we use inside the hello world folder the file app.js. And we use a function in export called lambda handler. So hello world, hello world, app, lambda handler export. So we use this and it's accessible for the sam local invoke via the resource ID we selected here, we created here, or that was created for us. So just that you know how everything is interconnected here. And then I will run this, start the docker container and do this thing. And as we can see, we get the body and its message hello world bar. So everything makes sense here. But now it could be that for whatever reason, someone forgot or mistyped this here and when it send it to us and got typo and now the foo doesn't exist anymore. And when we run this, yeah, the output isn't as we as we liked, classic JavaScript. No warnings, no anything just did this thing. And now we use something like dashboard or mossive to find out about this error. And now we have to debug it locally in some kind of way. So to do this, Visual Studio Code comes with an integrated debugger, a UI that can be connected to a Node.js running process that runs a debug server. For this, we have to create a debugging configuration. It's called launch.json. And this will have many configurations that will show up here at the top where we can use launch program. Yeah, its name is launch program. So if we change this, this will change. If we add more of them here, we will get more here like we have like two program two, then we will have this here. So you can see this is the launch.json. It's inside the .Visual Studio Code, a folder of our route from our project. It's created by Visual Studio Code. So to get this, the basics running, this is like you start your process, it will wait for you for a debugger to connect and then you will start your debugger and it will connect to your process. We need to follow in configuration. I won't type it everything by hand right now, but I will go over it after I copied it. So as you can see when I go in here, it's attached to SAM CLI. So what does this do? First it has a name. This is what shows up here. Then it has type node for Node.js. Request attached. This means that it just doesn't have to start any external process or something. It just tries to connect to some already running process and this process runs on localhost and port 9999. So when I start this, it will connect to this SAM process that runs in Docker and tries to get some debug information out of it. The other thing here is the local route. So debugging works when we set our break points here. So it needs some way to map the data from inside the Docker container to our file system here and this is the local route, is the file deer name. It's the deer name of this file we have opened here. And also the remote deer name and we get this here in the output somewhere. Here mounting s var task. So this is the mounting point. So what we get here is this from file deer name and what we need to add manually is the var task folder inside the Docker container. The protocol is inspector. This is the debug protocol and we won't stop on entry. We can set this to true for debugging purposes. Yes. So what will happen? We now need some kind of process that listens on port 9999. If we start our SAM local, it will just run and do its thing and be done with it and not wait for us. For that, we need to add another command line argument called D for debug and a port on which the process will listen. This will cause SAM CLI to start the process with a debugger server and it will just wait for our connection. It runs and then it says debugger listening and port. Everything runs and it doesn't execute the function now because we have to go into open our file because our launch.json uses file deer name and this is the file with the current focus which we opened here. So if I use launch and I press debug, then it will use the launch.json as a deer name which wouldn't work. So we need to have the file open we want to use. So we can set the break point here and then I would debug and it started at the very beginning. You can see this is some internalized internal file things that doesn't give us much information. That's why I am removing stop on entry where I set this on false so we don't end up in this file but at least it stopped and we can see the terminal debugger attached. Everything is connected and the debugger console works and we wait it on the first line. So now when we set continue, it goes to the first break point we have and we can now see in the side panel here in the sidebar the variables we have like event and foo is undefined. We already knew foo is undefined so let's look inside our event what is going on here. We used our query string parameter. Now we can see foo is written wrong. So now we can write some kind of code to fix this problem add some checker for this or send back to the client that we that he used the wrong that he didn't use the right query string parameter. So this is the basics of everything here. We can also add some watch expressions here event query string parameters. So we wouldn't have to go in here in every detail in this big object we get here but we would directly see um yeah when we start this process that so we could start it like now I forgot to to add the breakpoint could add a breakpoint and start everything here and come it would run and we have to start manually that's the problem you can see it um you can see the problem here we have already to go into the terminal and start our process manually uh which is like you're sitting here and you're clicking clicking clicking clicking and nothing happens and you're like what what is wrong what is going on here and you have to go to the terminal you have to type the same invoke command and everything and then it would run um and then we would go here and now we can see uh yeah it's directly here to see nothing nothing um we wouldn't have to dig into the object we see it directly here so um these are the basics it's you start in the terminal your stuff um you connect your debugger and everything works so and the next step would be to to improve the launch.json so it would do everything for us so we wouldn't have to go into the terminal anymore um I would look into the chat right now um if there are some questions no okay just everything works people are happy I think I hope I hope you're happy um yeah does anyone have any questions so far about what Key has already covered he's about to move to a second part of the talk right uh so we showed our e-mail addresses and Twitter accounts as well so if you want to reach out to us later after the talk could be as well uh so okay please please go on yeah okay good um so yeah everything this is done we are finished here and so um now as I said we have everything up and running here the next step would be the visual studio code integrate the debug as you can see the config is much more complicated but it isn't that much more complicated because most of these are arguments but yeah let's do this as you can see we can add another configuration we don't have to override the previous one if we want to use it for any reason um so what did I add here um debug with with event.json what do I do here at this time I don't I don't I don't inspect I launch what do I launch a runtime executable which is called SAM because SAM is installed globally so I can just use SAM like I did in the command line and I supply it with some runtime arguments um this these are basically the arguments I'm using here um SAM local invoke d minus minus d for for the debugger minus t for the template.jammel it will use the the template.jammel from the current working directory but you can supply it with a fixed one so it will always use this yammel file for you which is this here um as you can see there are already I'm already using a variables these are supplied by visual studio code and I already used it here um the workspace root is always the same for this for this workspace um so it will use the workspace and then slash template.jammel and that is this file then it will use the event dot uh the event.json from workspace root events slash event.json yeah this is the file we had we had here um this event file we use for example purposes um and then the selected text yeah I I use selected text here because um it allows me to to pass any text I select into the into this launch configuration yeah the what you can see here is that um we have many indirections here we have the the template.jammel that uses the hello world.function to locate functions yeah and you have in this configuration you have to say it's in this folder it uses that file and that file exports that handler and um but you you don't use hello world slash app.js colon lambda handler or something to to get to this file you only use here as you can see you only use hello world.function you only use this this uh this reference here so um one way to to get around this is to simply force everybody to call their handler the same as the hello world function resource id at the top um which is a bit restrictive so I had the idea to simply use this uh string as it is here and um edit as a comment at the top of my function handler like so and now I can select it when I run this debug with event.json yeah to go back here it says selected texts should be added as last uh command line argument to the same call so it uses the events from the event.json from the events folder it uses the template.jammel and it uses the function name I am giving it via a selected text and I selected hello world.function here so um so this will get passed to the as an argument so when I save this and run this it finished because well it didn't stop at entry yeah so let's do this again you probably want to add a breaking point from the code as well yeah sure sure sure we can add a breakpoint here and then run this like this so now we are going to as you can see I didn't have to run anything in the command line um I'm getting some of the command debug console outputs in the debug console and yeah now I can simply go into a file select this this comment at the top and it will pass everything to the SAM CLI and um yeah we can debug it from there like you can see it I think the debug console also shows the command I passed you can see here I used here hello world function this is what I think when I when I use this this um this code part here and would run the debugger again it would pass lambda handler as you can see here and it doesn't find the lambda handler because the template didn't define any function any lambda handler function it tells you uh this is what it what is defined for function so you can use these functions but you can't use this this um this string here as I said you can do the different things with that um I I use the selected text yeah which requires me to write a comment at the top yeah but you could also force everyone to to do it like this like saying they have to call this the same way as their resource thing here in their template file yeah it doesn't have to be called lambda handler it has to be called hello world function the same as this here and um then you wouldn't have to write a comment then you could run this directly here you can see hello world function works and invoking hello world and it stops there and why because I didn't have a break point it didn't go inside that function but um yeah it still works now I think this is matter of taste I I did it with with comments you could also use file names this is where we go to the next point that is important you can see all these variable substitutions I use tis uh file your name and workspace root and selected text and um yeah this is um defined in Microsoft gives you these variables in visual studio code and um you can use this this site here um to find every every one that is um is available to you you know um um so you can use this this whole bunch of variables to define your own mechanism how you pass the function name into the debugger so it uh knows the or into the the SAM CLI so it knows which which function you have to run you could use a file name you could use a handler name you could use a directory name or whatever now I used uh selected text because yeah it requires me to select text before I have to run it but um yeah that that would be a way to do it another way would be you don't use select the text here you explicitly write here your your function name yeah and then it would only work for this function and this event you can can write um configuration for every function and every event permutation but um yeah it's the question of of taste I think if you like it like that you can write like 100 um 100 uh configurations here or you can write run that requires you to do some work to get it running um yeah uh what what the the next point that is um in that I found interesting is that you don't did you just you you don't need only the the function name but also the event name so um while this is rather flexible it can use for different functions it works only for the hard coded event name in this place um yeah you you can imagine that this is already a bit problematic because if you have like 10 different functions you probably don't want to run them with the same event often you have um like 10 events for testing purposes you have a broken event you have a working event you have an event with that that content with that content everything you want to test and um so you would also write to have still have to write a event um for every event such a configuration here which could get quite cumbersome and this is where I would go to the next step um an idea that I had about debugging um which would incorporate some kind of script um and make the whole thing a much more flexible so the idea is um I had this repository here and we did this we did that and now we're going into this as you can see it's a bit easier because most of the stuff that we had configured inside this we had to write inside this configuration we can now write inside the script that I will write later um it will debug with script yeah that's the name it will run it launch an executable in the workspace called debug.sh we don't have this at the moment so I have to create this so the debug.sh will have this content the the basic idea is it's a small script um if you if you don't count these new line things here basically three lines of bash code um what it does it takes the first argument it gets and splits it into an array and then it passes the first array parameter uh the first array uh piece to the to the SAM local invoke function um as function name and the second one as event name well and what the launch uh dot jason um does is it will launch this script it will use the selected text as its only argument and and then all the uh start this thing yeah and um as you can see the only argument here will be split and the second part will be used as event and the first part will be used as um as function name and you can see the other arguments for the same um command are encoded in this in this debug.sh so we don't need all this stuff here anymore we just need our selected text so and how does this work um it will work as I did with my example before um we can write a comment and define um as you can see the oops file define with function name and event name now so function name is in a world that function and the event name is called like this we could also have a new file event broken jason for our debug purposes like we could use this and event broken and so we have here a working event and here we have our broken event and we could use event and event broken this is why I used comments before because of the script thing it would be uh bit bit tricky to mark this and then mark this yeah I know it works uh it's just a bit uh higher level editor handling yeah and now you just had to mark this this would be used in the launch to get past it here into the debug s8 and the the current open file yeah this is this is the file here would also be passed here and then we could say we went to to look here in our debug uh here's our breakpoint so we would stop here then we would look here we have a new script called debug with a new configuration called debug with script and then we would run this and then I have forgot something somewhere what did I forget what did I forget whoo whoo whoo no idea let's throw everything out you run it again what was the the message it said that I um that I used that something in the configuration was broken select the text cannot be ah I didn't select anything yet so I have to select something here and then run this here and okay so we are not with property form it is the debugger this is going to be an error channel selected text is this right this is right launch debugger s8 file name yeah that's right ah I think I am yeah this is also right oh wow classic yeah what did I do wrong I need to select the text yes yeah this is property of any final debugger type something wrong here do you I guess I'm gonna need to run uh this here uh yeah it was an error but it wasn't that here said we're gonna need to run uh how to debug the debugger haha yeah it's it's a bit uh strange right now I didn't have this probably did I write something wrong it's mine it's debug.sh debug.sh a workspace root everything is written right um the port is right the address property okay I guess we can send uh everyone a message later later with uh instructions to fix the issue after we narrow down to the every cause uh so the the idea is I think uh can you please go back to the app.js yeah the idea is the idea is that you can select this and or select that and you can start your hello world function with that event or with that event and as you can see it will it will use the dot event dot slash event slash the selected event dot jason and the selected function dot jason yeah and the selected function name yeah so the idea is that you could have like hundreds of these things here and then you would like go ah this is broken why this is broken I need this event you know and then you would like go in here run this and um everything would work normally and um you would see it would would run normally like like it did before yeah yeah yeah one one advantage as well I see having these comments uh as comments on the code is that if you have someone else um I got it I got it I got it aha moment yeah it's it's not you can see it like ah the event uh isn't it the directory but so now it has you know all right you didn't have redacted and it's now I do it right I don't think it's it's always wrong folder or wrong um permissions yeah those are the main main bugs yeah okay so don't don't forget to uh set your fire permissions correctly yeah uh for everyone so the I think one of the main advantages of using these approaches that if you have someone else uh coming into your team and uh he needs to work with his code he's not familiar with the code base yet and he needs to debug an error if you have instructions clear instructions as comments like these at the top of your lambda function handler with all the parameters that can use the arguments that can use for the debugger you would be a lot easier for this person to to start digging into the code and actually get into the root source of the error so this can save a lot of time for other people that might join your team in the future I think this is one of the key takeaways for cat approach so it's not only more convenient but it also makes developers lives easier in the long run if you are working that team okay great uh so okay we we have a few a few questions um so I missed one question sorry um at the last um we we open so someone sent a question how to handle course issues um all that using this fashion so course I could be but so it's related to actually API gateway or whatever you're using as an interface that you receive htp calls uh on your lambda functions uh so you need to set up if you're using API gateway you need to set up um it to allow course connections uh and you're going to need to address these in your lambda code as well uh yeah I I could show this if you if you like yeah please go on okay so it's it's not related to debugging in general but the point is one one part is you have to to add cause to your um to your function here yeah um um this is um how should I it's it's some some part here I think it's even called uh method properties cause or something I think it's like here cause and then it's like uh this for for cause well was it I think it was was like this but this is not it's only the half of this stuff uh you have to to return the right the right header you know if you write your function you you see you have to status code you have the body and everything and um I don't know what the real name of this is right now but you can like set headers or response headers uh or something I don't know what what the real um name here is but um here you can set some some headers I could also be that it's like this and then um you could define a header a cause header like you um you know from HTTP yeah it's you have to to explicitly set this thing to um allow um allow or how is it called I I don't remember how cause is uh it's called but it's like cause header and um and there you have some they don't don't remember how all these things are called it's something like access control allow is something I I can't remember how it's called but you have to yeah you but you I think yeah allow origin yes allow origin was that if you use if you use an asterisk it's going to accept connections from any domain or you can select which domains you want to respond to requests yes yes but you have to add this into the response object you return from your lambda or else it would be missing um I had this problem rather often it's like you go to the template you set your cause stuff here right and then you you already so you're still missing the right cause parameters um I fixed this by adding the the header explicitly to my function response and then it would work yeah yeah of course can be can be a thing but it's it's uh more related to the HTTP whatever you're using to interface AWS lambda with the public API with the board so that's where we need to configure everything and and obviously you need then that should be responding correctly to accept those connections another question you receive this can it work dynamically where if it can change the code and save it automatically starts the debugger running so I guess the question is if you're fixing an error you make a change you save the file is it possible to automatically run the debugger as you save the file you know okay um I I think it's technically possible but I don't know how what what I know is that you can run different programs every time um you save a file and these uh these programs will be called with some kind of parameters and I think you could um write a script that would get the right parameters and start the debugger but I never done it okay uh so if we find out a way to do this we'll send uh you know by name to you guys um the other question is can we debug a AWS serverless application if it is debugger or only serverless functions um so a serverless application needs is more of a high-level way of kind of declaring our serverless AWS name this text so we can declare multiple functions in direction with API gateway it's it's it's kind of a wrapper to AWS confirmation um right case so it's it's it doesn't I don't know if it makes sense to you talk about debugging an application a serverless application it's yeah it's um I think the serverless application is more related to the API gateway or a bunch of services and the serverless function is related to the lambda yeah um so I think debugging like this would be applied to serverless functions and yeah all right you might want to to kind of test your entire stack uh so maybe you want to test the interaction between multiple functions but um that would be if you are debugging if a lambda function that calls other functions in in background um you would be able to to do this with these debugging style that cages outline no um okay last question is do you use localhost URL uh for your testing or do you bind with some DNS server locally for your development but you're using localhost right I I only I mostly use localhost um I try to to write my code that it doesn't that it isn't concerned with the host it's running on um I had some issues in the past with with with some applications that wouldn't run anymore because it would require the right domain and the right path and the right port and everything um so you would have to update your host's um file and create every recreate everything so it would be exactly like in the in the cloud and um this was always a pain when working with especially with new developers they would come and they would run everything and then you would like okay yeah we have this big document where we write wrote everything down you have to be doing to get your first debugging running um so I try to get all things decoupled as as uh as much as possible so I can use localhost locally and be done with it I just need the right event and um the right function and it works and I don't have to recreate everything that is in the cloud yeah yeah I agree it would be much easier especially for new people coming into the project as I mentioned uh so just standardizing as localhost for everyone you call collaborating uh to a project is I think is the best way to go okay uh so we've covered all the other questions so I'd like to thank everyone for joining us for this uh tech talk we will send the the presentation and the recording of the session I email you to everyone uh and stay tuned we will uh publicize other tech talks that may run in the future so stay tuned and find us for future sessions as well thank you very much goodbye hey thank you very very much for the explanations it was very very very helpful to me and I trust it was very helpful to everyone attending today as well would you like to say just the last words yeah I'm happy that you had me and I hope you learned something new about debugging with virtual studio code awesome all right thank you thank everyone have a great week bye bye