The Best Way to Add Health Checks in Any .NET App

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody I'm Nick in this video I'm going to show you the best way to implement health checks for your dotnet applications I've worked for small companies and huge billion dollar companies and in any project ever we hand health checks in place you need to be aware that things go wrong when they go wrong and be alerted and in today's day and age especially with containers and clusters you need to know when a container in your cluster is dead so the traffic can be rerouted to the healthy applications in that cluster so in this video I'm going to show you how you can get started with health checks in.net with the built-in.net health tech support and also show you how you can expand it in a few very nice and really really cool ways to make it very easy for you to implement very complex HealthWorks if you like those content and you want to see more make sure you subscribe during the seven notification Bell and for more training check out my courses on domtrain.com alright so make sure that I have here I have a simple customer API it doesn't really have much that you need to care about other than the endpoints we can create a customer in the system we can reach retrieve a customer get all customers update a customer or delete a customer it's a very simple crowd API and it uses for example here a postgres database to make all the actions and also because as part of the contract of this API we use a GitHub username because the user needs to be a valid GitHub user if we take a look over here to this GitHub Service as part of validation another functionality we check that the user is also a valid GitHub user so we have the API itself that needs to be alive and healthy but also we have dependencies both in our database that postgres database and on GitHub a third-party API we need to know that those things are healthy for application to be healthy if the database is unhealthy then the application is unhealthy and if GitHub is down then we are either unhealthy or degraded and that's a decision you have to make on your end at what point is your application completely unhealthy and it should not be sent traffic and at what point is it degraded meaning it can maybe stay still handles some traffic but not all or there's an issue that it might recover from and so on now if I was to just run the API everything will run fine and everyone is happy and if I try to create the user both GitHub is up and my database over here in Docker is up so no problems will be detected or happened the action will actually happen successfully however if the application is running it starts is healthy it's fine as you can see it can handle traffic but suddenly the database goes down I just go ahead and I stop it the application is still running and if it's running in a cluster or in a system you won't know that this actually is unable to Hull requests until someone sends a request so if I try to go ahead and create a user I'm going to get a 500 internal server error because the database is not running I can quickly demonstrate this by going to password and just calling the customers endpoint and as you can see after some time off period I think five seconds we're going to get our exception we have four seconds over here so as you can see failed to connect to that address because it's down ever eventually the database you know recovers and we try to send those requests it will respond it will be fine but during that period it is unhealthy and everyone who tries to access it will see an error message we don't want that experience both we want to prevent it and be alerted before the user actually sees that and has a bad experience but also if this leaves behind a traffic manager or a cluster we don't want any traffic to be going to that service we won't deem it as unhealthy and then periodically see if it recovers so what we're going to do is use the built-in.net health checks now asp.net core already has that functionality in it so all we need to do here is go into the services and say builder.services.ad health checks and that's it to add all the services needed and then we need to register the middleware associated with this and remember Midway is actually sequential so the position does matter if we register it here above Swagger then Swagger is agnostic of the health check if we have it after the https Direction then it will take that into account as well and when we can simply say map health checks and that is it now we need to pass down the end point and where I want to have this is actually forward slash underscore Health that's a very common a convention for having your meta endpoints whether that is health or metrics or stats or something like this and now the moment I do that and I go ahead and I run my API I can go to password and I can say health over here and if I call that we're gonna get healthy and 200 okay now the problem is that if the database does go down and the application is running and I call this again it is still healthy because it doesn't have the context of what the dependence is so we want to introduce that to that concept what I'm going to do is for now restart the database and let's create my first health check I'm gonna go ahead here and create a health directory and create my first class and I'm gonna call that database health check now for this to be a valid health check it needs to implement the I health check interface and then the missing members so all I'm having here is this context over here and this cancellation token which can be used to cancel a health check and I need to implement the body of this now for a database check this is very simple actually can we open a connection and can we execute a query and that is it and since I already have here a database connection Factory I can inject that here and say private read-only idb connection Factory grab a connection from that so I can say in here turn this into async and then have a try and catch and that is actually important because we're going to be using that exception if it happens remember we want to check for catastrophic failure so we have that here and then we say using VAR connection equals await DB connection Factory and create the connection now at this point all I need to do is create a command set the command text to select one that's going to be enough can you execute the query and then just run it and if this all happens at successfully we can simply say return health check result healthy that it's all good however if at any point here we get an exception then that indicates that the database is unhealthy and this is where I'm going to say health check and in this case I would say that this is an unhealthy State not a degrading stage because without the database there is no API so unhealthy and I'm gonna pass down the exception as well to give more context to this check so now that you have this all I'm going to do is go back to program.cs scroll the way up and say add check database health check and then I'm going to give it a name database or postgres or whatever you want and now I can just run it and it is going to work the API is running the databases up and running if I say health as you can see this will trigger and if I stick a break point here you're gonna see that it's gonna step in here and do all the checks so it's gonna go in check the request send the request and eventually say that it is healthy but if the database base goes down suddenly and I try to do the same thing look what happens suddenly unhealthian 503 and now if I have dueling alerting monitoring things will trigger and I'm gonna start getting emails or slack notifications and so on to say hey something happened with this service and I can do the same with the API as well and it's the same thing all I'm going to do is create a new class called GitHub health check and that's going to look in a very similar way we inject the GitHub service we try to get a test user in this case me if this executes successfully then everything is good if we get an exception then Mark it as unhealthy and move on now IW could this be a degraded state it could because now you're gonna have create an update not working but get or delete will be working you have to manage your way around this but I'm going to leave it as unhealthy to simplify the flow over here so now we started the database I'm going to go to program.cs and add the second check as well so GitHub health check over here and call it GitHub and that's it and if I run this and I go ahead and I call that endpoint what I'm going to get is healthy because now both checks will get triggered and they all gonna be good now here's where this gets interesting just saying healthy might not be good enough for you especially if you want to use that Health checking point for internal use which normally you would you wouldn't publicly expose it unless you whitelist who can actually call this and we're gonna see how we can do that but just healthy isn't enough for me and we can actually make this better because we can customize the response writer for that health check and it's very easy to do all I'm going to say is new health check options and you have a bunch of them here but the one we care about is this one response writer Now respond writer gets the HTTP context Health Report and returns a task that writes to the response and you can write your own but we don't need to do that because there's many people who actually use health checks that have written some excellent tooling around those one such tool is the following you get package we're going to go ahead and paste this asp.net Foreigner dot write health check UI response and that is it that delegate now is matched and passed here and if I say debug now and I go ahead and I run this and look what happens eventually when the API is running you're gonna get the healthy and then both the total duration of both health check requests and each individual entry so the database took this long and it's healthy and the GitHub one took this long and it's also healthy if I go ahead and I stop postgres and then I say send it this is overall unhealthy but we can see that GitHub is actually healthy but we can also see that the database terminated due to an Administrator Command which is what I did by turning it off so it's very interesting that you get more context now and that actually happens because we are passing that exception object in that response over here in the health check here we go that's the thing that makes the difference but here's where this becomes completely Bonkers and just out of this world and that's why I love the community of.net if I go to nougat and I delete this UI in the client part and I keep asp.core.healthtracks then as you can see over here there's a family of packages from SQL Server to your eyes to read this to mongodb progress Kafka Network might like look at all this all of these are individual vendor sort of things like kubernetes here Raven DB uh Zach Prometheus for Publishers as well documentdb events or send grid so many the one we are using is postgres so I'm just gonna go here and install npg SQL and just quickly install that I'm gonna go ahead and comment out the one I wrote this database check and I'm gonna say dot add n p g SQL I'm gonna pass down the connection string for the database and that's it I don't need to write the check myself there's actually one already and it's very likely that anything that you're using in terms of a dependency there's going to be a check for you to use due to this family of libraries so I'm going to go ahead and just run it and now I'm going to just run this health check endpoint and the database npg SQL is healthy and if it eventually goes down let's just stop it then as you can see we get the same support as before it is fantastic it's excellent you don't need to write a sync line of code and I highly recommend you give the project and the family a star on GitHub I'm going to put a link in the description lovely lovely packages now a couple of last things I want to mention you might want to limit who can call that endpoint like I said before so you can do things like require host so you can require specific host or a set of hosts to actually be able to call this or you might require authorization for something to call this or you can do what most people will probably do which is limit this endpoint within a network and only allow that internal Network to actually call it which is how absent implemented as well but it's good to know you have a bunch of extension methods here that you can actually use to change the behavior of who can call it and how they can call it but now I'm not from you are you using health checks and did you know about this family of libraries that Implement all of these different vendors and health checks for them leave a comment down below and let me know well that's all I have for you for this video thank you very much for watching especially next to my patreon so make it videos possible if you want to support me so you can find the link description down below leave a like if you like this video subscribe or like this in the Bell as well and I'll see you in the next video keep coding
Info
Channel: Nick Chapsas
Views: 80,072
Rating: undefined out of 5
Keywords: Elfocrash, elfo, coding, .netcore, dot net, core, C#, how to code, tutorial, development, software engineering, microsoft, microsoft mvp, .net core, nick chapsas, chapsas, dotnet, .net, asp.net core health checks, health checks, .net health checks, c# health checks, health checks .net, health checks in .net
Id: p2faw9DCSsY
Channel Id: undefined
Length: 12min 31sec (751 seconds)
Published: Mon May 29 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.