Learn how to set up logging and middleware in FastAPI apps and ship logs to Better Stack for analysis.
Ask about this video. Answers come from its transcript only — with the timestamp, so you can check them.
Generated from the transcript and can be wrong — check the timestamp.
Key Takeaways
- Middleware can be used in FastAPI to log all incoming requests and outgoing responses.
- Better Stack platform enables centralized log analysis and event detection.
- Uvicorn is the recommended async web server to run FastAPI applications.
- Python’s logging module allows detailed customization of log output format and handlers.
- Organizing logging code in separate modules improves maintainability.
What the video covers
- Introduction to setting up logging in FastAPI applications using Python.
- Creating middleware to log details of every request and response.
- Shipping logs to Better Stack platform for analysis and searching important events.
- Setting up a Python virtual environment and installing FastAPI and Uvicorn.
- Building basic FastAPI endpoints with async handlers.
- Running the FastAPI app with Uvicorn and enabling auto-reload.
- Configuring Python logging with formatters and handlers.
- Creating a dedicated logger.py file for logging utilities.
- Implementing middleware to capture and log request/response data.
- Using Better Stack’s logging tools and documentation for enhanced log management.
Chapters
- 00:00Introduction to Logging in FastAPI
- 02:02Defining FastAPI Endpoints
- 04:02Running FastAPI with Uvicorn
- 06:04Setting Up Logging Formatter
- 07:53Log Record Attributes and Message
- 09:47Configuring StreamHandler for Logging
- 11:34Installing Logtoil Python Package
- 13:26Logging to File and Standard Output
- 15:29Creating Middleware for Logging
- 17:23Implementing Async Middleware Dispatch
Full Transcript — Download SRT & Markdown
Speaker A
In this video, we're going to learn how to set up logging with the FastAPI framework in Python. We're going to see how to set up middleware in order to log out details of every single request and response that comes into your application. We'll also see how to ship those logs to Better Stacks platform in order to analyze and search the logs and find important events that are occurring in our application. Let's get started.
Speaker A
application and we'll also see how to ship those logs to better Stacks platform in order to analyze and search the logs and find important events that are occurring in our application let's get started now let's start by creating
Speaker A
Now, let's start by creating a Python virtual environment and installing FastAPI into that environment. I have the documentation open at the moment, and we'll leave a link to this below the video. What we're going to do is go to the install FastAPI section, and we're going to run this command here: pip install fastapi all.
Speaker A
API section and we're going to run this command here pip install fast API all now I'm going to cross over to VSS code where I have a directory with a main.py file that's all that's in that folder and what we're going to do to start with
Speaker A
Now, I'm going to cross over to VS Code where I have a directory with a main.py file. That's all that's in that folder. What we're going to do to start with on the terminal is create a Python virtual environment using the venv module. So python -m venv, and let's give this environment a name of venv_fastapi. Once we've run that command, you need to activate the virtual environment. I'm on Windows at the moment, so what I'm going to do is activate it with this command, and you can see that that is activated. Now, if you're on a Unix system, you can use the source command in order to do that.
Speaker A
on windows at the moment so what I'm going to do is activate it with this command and you can see that that is activated now if you're on a Unix system you can use the source command in order
Speaker A
What we can then do is install FastAPI, and actually, I'm going to just paste that command that I copied from the documentation. That's going to install FastAPI as well as other dependencies such as Uvicorn. Uvicorn is the async-ready web server that we're going to use to serve the FastAPI application.
Speaker A
is the async ready web server that we're going to use to serve the fast API application once that's done what we can do is we can actually create a small fast API application and we'll build some logging into that application
Speaker A
Once that's done, what we can do is we can actually create a small FastAPI application, and we'll build some logging into that application, including building a middleware slightly later in the video. So to start with, let's import from FastAPI the FastAPI object. In order to create a FastAPI application, the most simple thing you can do is instantiate that and store it in a variable, which we will call app.
Speaker A
in a variable which we will call app and then using this app object we can Define handlers and endpoints in the fast API application so I'm going to Define an endpoint that takes a get request and the path for that is just going to be a
Speaker A
Then, using this app object, we can define handlers and endpoints in the FastAPI application. So I'm going to define an endpoint that takes a GET request, and the path for that is just going to be a slash. So it's the base path in the application. Then, what we can do is define an async Python function, and this is the handler for the root. So let's call this function index. Then, we can return a bit of content, and in my case, I'm going to return a dictionary here, and we'll give it a message of hello.
Speaker A
case I'm going to return a dictionary here and we'll give it a message of hello so a very simple endpoint here it returns a python dictionary containing a key message and we can type in that return type if we want using this syntax
Speaker A
So a very simple endpoint here. It returns a Python dictionary containing a key message, and we can type in that return type if we want using this syntax here, until the FastAPI function that this is going to return a dictionary. FastAPI will then convert that to JSON.
Speaker A
be to a URL that we're going to give a path of upload videos and I'm also going to name the function upload videos and we can change the message here to video uploading and later on in the video
Speaker A
Now, what I'm going to do is replicate this endpoint. We're going to create one more endpoint, and this one is going to be to a URL that we're going to give a path of uploadvideos. I'm also going to name the function uploadvideos, and we can change the message here to video uploading.
Speaker A
that was the web server that we're going to use and at the bottom we're going to run the web server here we're going to check if we're running this file as a python command and then we're going to
Speaker A
Later on in the video, we're going to introduce a bit of latency for this function to simulate a long-running request that you might get, for example, when you upload a video.
Speaker A
order to run this is make the terminal a little bit bigger here and we're going to run the uicorn main app command and I'm going to pass the D- reload flag to this so that the server will reload when
Speaker A
So now we have two handlers. Let's import Uvicorn at the top, and remember I said that was the web server that we're going to use. At the bottom, we're going to run the web server here. We're going to check if we're running this file as a Python command, and then we're going to call the Uvicorn.run function if that's the case. We pass our app object into that function, as well as some details here for the host and the port, and you can change those if you need to.
Speaker A
can add the other endpoint here of upload D videos and we're going to get back that different message for the second Endo so we have a fast API application albeit very basic but how do we add logging to this application let's
Speaker A
Now, what I'm going to do in order to run this is make the terminal a little bit bigger here, and we're going to run the Uvicorn main:app command. I'm going to pass the --reload flag to this so that the server will reload when any changes are made to the code.
Speaker A
to bring a couple of imports in we're going to import the logging module and also the CIS module from Python and then what we're going to do below that is get the root logger so I'm going to get that
Speaker A
So we now have a server running on localhost:8000. If you go to the browser, you can see that at the main endpoint here, we get the response of message hello. We can add the other endpoint here of uploadvideos, and we're going to get back that different message for the second endpoint.
Speaker A
string or none and that's going to return a logger with the specified name and create it if necessary and if you don't specify a name as it says here it's going to return the root logger so this line of code is going to give us
Speaker A
So we have a FastAPI application, albeit very basic. But how do we add logging to this application? Let's go back to VS Code, and we're going to create a new file in the project that's going to be called logger.py. We're going to define some utilities from Python's logging module in this particular file.
Speaker A
create a variable here called formatter and that's going to be equal to an instance of a logging do formatter object now this takes some arguments the most important one is the format so let's pass in a format string here and
Speaker A
So at the top, I'm going to bring a couple of imports in. We're going to import the logging module and also the sys module from Python. Then, what we're going to do below that is get the root logger. So I'm going to get that logger by calling a function in the logging module, and that's going to give us back an instance of a logger in Python.
Speaker A
hand side here it's the log record attributes so a log record basically repres presents a piece of log output and this log output can have some attributes that are predefined in the logging module so if we scroll down here
Speaker A
So what we're going to call is logging.getLogger. This function can optionally take a name; it can be a string or None. That's going to return a logger with the specified name and create it if necessary. If you don't specify a name, as it says here, it's going to return the root logger. So this line of code is going to give us back a logger instance in Python.
Speaker A
the level name in the logging package refers to the debug info warning error or critical log level and each of these have a corresponding number that determines the severity and the higher the number the more severe the log event
Speaker A
What we're going to do after that is create what's called a format. A formatter in the Python logging package is going to determine the output format of your log records. So let's create a variable here called formatter, and that's going to be equal to an instance of a logging.Formatter object.
Speaker A
code and we're going to create a log format here so the first thing we're going to Output is the time at which the log record was created and then we're going to put a space and a Dash and
Speaker A
Now, this takes some arguments. The most important one is the format, so let's pass in a format string here. We're going to set that equal to a string that will determine the output format of our logs.
Speaker A
defined in your application and then I'm just going to put another Dash here and we're going to Output the message that's the actual message passed into the log method as we're going to see very soon so this is a very simple format for our
Speaker A
Now, what I'm going to do is go back to the documentation for the logging package in Python. What we're going to look at is on the left-hand side here, it's the log record attributes. A log record basically represents a piece of log output, and this log output can have some attributes that are predefined in the logging module.
Speaker A
going to be a loging do stream Handler and and this can take any stream as a parameter but if you don't specify one it's going to send the output to standard error so just to demonstrate this I'm going to pass in standard out
Speaker A
If we scroll down here, you can see some of these attributes that we can reference in our log format. For example, this one here is for a human-readable time when the log record was created. We also have other ones such as the level name and level number.
Speaker A
Handler instance and the main argument we need to provide here is a file name so let's provide a file name of app. log once we've done that we can set the formatter so basically we're going to take each of the handlers like the
Speaker A
The level name in the logging package refers to the debug, info, warning, error, or critical log level. Each of these has a corresponding number that determines the severity, and the higher the number, the more severe the log event is. We'll leave a link to this below the video.
Speaker A
also going to do it for the file Handler and we're nearly done what we need to do now is we need to add the handlers to the logger instance so we have the logger that we created at the top here
Speaker A
There are many of these log attributes, but what we're going to also reference is the message, and that's the output message that's passed into the log level method.
Speaker A
this application so I'm going to use the stream Handler and also the file Handler and the Handler's property is telling the logger where to send the output records so it's going to send them to standard output and also to the file
Speaker A
So let's go back to VS Code, and we're going to create a log format here. The first thing we're going to output is the time at which the log record was created. Then, we're going to put a space and a dash.
Speaker A
logging doino so we now have the configuration for this logger and we've set some format Ms and handlers on the logger what we can do now is go back to main.py and at the top here what I'm going to do is import from logger the
Speaker A
Actually, I'm going to move this to a new line so we can see the entire line better. After the dash, we're going to put the level name, which could be info or error or any other log level that's defined in your application.
Speaker A
we can do is make the terminal a bit bigger at the bottom and if I save this file it's going to reload the application and it says starting API that was the message we passed in and it's got the format that we specified
Speaker A
Then, I'm just going to put another dash here, and we're going to output the message. That's the actual message passed into the log method, as we're going to see very soon.
Speaker A
log statements to our Handler functions in fast API so let's go to the index function and I'm going to put a very simple log message in here and again we're going to call the logger doino function and the message I'm going to
Speaker A
So this is a very simple format for our log records. What we're now going to do is create some handlers that are going to determine where the log records are going to be shipped to. Let's create a couple of these.
Speaker A
if we go back to the browser here and go to our upload videos endpoint if I refresh this page and go back to the terminal on vs code you can see we get this output log here containing the time
Speaker A
The first one's going to be called streamHandler, and that's going to be a logging.StreamHandler. This can take any stream as a parameter, but if you don't specify one, it's going to send the output to standard error. Just to demonstrate this, I'm going to pass in sta...
Speaker A
have in the main.py the ability to import that logger and use that logger so we use it here and we also use it in our Handler functions as well now soon we're going to add a middleware to log
Speaker A
output for every request but what we're going to do before that is we're going to add a Handler that allows us to ship our logs to better stack and this is vital for centralizing your logs across different services in a single place
Speaker A
where you can then search through them and build some analytics around those logs and also helps with identifying events or anomaly that are occurring in your application so what we're going to do now is go to the better stack log
Speaker A
page and we're going to create a source that allows us to take the logs from a particular service so let's connect our source now and we're going to give it a name here and let's give it a name of
Speaker A
fast API demo and we're going to select a platform and we can search through the list available here and we're going to select python so let's create that source and then we're going to get back a token as you can see here let's copy
Speaker A
that token and what I'm going to do is go to logger dopy and right at the top of the this module I'm going to add the token here so let's create a variable called token and we're going to set that
Speaker A
equal to the string that we get back now in a real application you should extract that token to the environment and then read that in securely and of course that should not be put on GitHub or any other
Speaker A
source control system but we're just going to leave this here for demonstration purposes in this video but make sure you don't hardcode these types of tokens in your applications so what we have now is a source and we can now
Speaker A
ship our logs to this source using the token that we've been given and in order to to do that we need to bring a new package from better stack into our application so I'm going to go to the
Speaker A
better stack documentation for logging in a python application there'll be a link to this just below the video what we're going to do to start with is copy the PIP install command and we're going to install the log toil python package
Speaker A
and this is basically a package that allows you to ship your logs to better stack so let's copy that command and go back to VSS code I'm going to stop the fast API server and we're going to paste
Speaker A
that command in and install the log tail python package once once we've got that installed we can then use that package in our application I'm going to go back to the documentation and you can find the instructions on how to use this with
Speaker A
a python app in this documentation so what we're going to do is import the log tail Handler so this package gives us the log tail Handler that we can use to ship logs to better stack so let's import that at the top and we're then
Speaker A
going to take the log tail Handler and we're going to go to the section that we have here where we created two handlers and we're going to create another one just below this and this is going to be
Speaker A
called the better stack Handler now we're going to set that equal to an instance of the log tail Handler and what we need to pass in here is a source token and we need to set that equal to the Token that we got from
Speaker A
the better stack user interface when we created that source and of course we saved that token at the top of this file on line five so we're going to reference that token here in the argument and once we've created this better stack Handler
Speaker A
what we can then do is go down to the logger do handlers line and we're going to add our new better stack Handler to that list so now we have three handlers in the application and of course you can
Speaker A
add and remove these as you wish you don't need to use all of them if you don't need to log to a file you can just remove that Handler but I'm just going to keep logging to all three of these
Speaker A
and what I didn't show earlier on was actually the app. log file you can see the logs that are being collected in this app. log file and this corresponds to the file Handler that we defined here where we told the file Handler we're
Speaker A
going to send those logs to the app. log file so we have that on the left hand side our logs are going to standard output they're going to the file and now hopefully they're going to go to our
Speaker A
better stack Source via this log tail Handler so let's run the application again on the terminal and once that's running what we're going to do is go back to this page here for upload videos and we're going to refresh the page and
Speaker A
we can do the same at the other end point where we just get back the message of hello if we go back to the better stack platform here and we go to the live tail for the logs we should now see
Speaker A
that we are actually getting getting these logs coming back to the better stack platform and we can click these logs to get more information about them so for example we get the fil name that emitted that log we get the message and
Speaker A
these contain very basic messages at the moment and we also get some information about the level and severity as well now you can add your own key value pairs to the python log output and we're going to see an example of that very soon what
Speaker A
we're going to do now is we're going to create a middleware in our fast API application that's going to log details of every request that's coming into the application now let's start by going to the fast API middleware page so a
Speaker A
middleware is a function that works with every request before it's processed by a specific path operation which is basically a Handler function and this function also can process every response before it returns it to the client and the benefit of that if we go back to vs
Speaker A
code and look at the code that we have in main.py if we look at the two Handler functions we have two outputs here to logger doino now imagine that contained the same data and we had it in 50
Speaker A
different endpoints we might want to consolidate that and instead of adding log calls in every single Handler if we have a common functionality there we can extract that to a middleware that's going to run before every request so how
Speaker A
do you define a middleware in a fast API application let's go back to the middleware page and as we've seen we have an app object when we instantiate fast API we can also use another decorator here the app. middle we
Speaker A
decorator so I'm going to copy that decorator and we're going to go back to main. Pi and I'm going to Define this middleware just above the handlers and later on we're going to extract that middleware to its own file so we use The
Speaker A
app. middleware Decorator and then I'm going to Define another async function and let's call this one log middleware now a middleware in fast API it can take two arguments first of all the request object that is passed in as the first
Speaker A
argument and then we have a function passed in as the second argument called call next so let me just copy these and we're going to bring them into the code here and we need to import the request object from Fast API so let's do that at
Speaker A
the top now what I'm going to do within the middle wear function is I'm going to create a python dictionary that we're going to call log dictionary and that's going to be equal to a dictionary with two keys and the first key that we want
Speaker A
to add is for the URL we can get the URL for this request by using the request.
Speaker A
URL property that gives us back a URL object that contains another property called path and that will give us the full path for that request and we can also add a second property to the dictionary and that's going to be the
Speaker A
request. method and that's going to tell us what kind of method that was sent to the back end was it a get request a post request or so on so our middleware now has a dictionary containing a URL and a
Speaker A
method what we can do is we can call logger doino here and I'm going to pass the log dictionary through to that and what that's going to do is it's going to Output that log dictionary as the message for this logger info call and
Speaker A
because we're using this as a middleware this is going to be run on every single request that comes into the fast API application now we need to then progress the middleware onto the next middleware in the chain or to the actual Handler
Speaker A
function if it's the last middleware so what we're going to do in order to do that is we're going to create a variable called response and we're going to call this function here that was passed in as a second argument it was called call
Speaker A
next we can call that and pass the request into that now because we're in an async function here we can await that function returning and what this is going to do is it's going to return the actual response that's to be sent to the
Speaker A
client and at this stage we can modify that response for example we could add an HTTP header that we want to send back but all we want to do is just log out this data so what I'm going to do for
Speaker A
now is just return the response to the client so this is a middleware that does some operations on the request coming into the client and it logs out some data and then it simply Returns the response we're going to see later later
Speaker A
on that we're going to add another property to this log dictionary that can only be calculated when we've generated the response for the client so we are going to modify the code in between generating that response and returning
Speaker A
it a bit later in the video so let's now test this out I'm going to remove these log calls that we have in the function we don't need those anymore and we're just going to see the log output for
Speaker A
this middleware here so let's save the file and go back to our page here I'm going to refresh this page and we get back the same response but what we need to know is has the middle wear run in
Speaker A
the application so let's go back to better stack and you can see this log record at the bottom here if I expand that you can see we get back the message containing those two properties that we added to the dictionary so the URL which
Speaker A
is just slash and the method which in this case is get and we can test that for the other endpoint so slash upload videos if we do that and go back to the live tail this time at the bottom you
Speaker A
can see we get back the message here containing a different URL it's still a get request but the UR URL has changed to/ upload videos so the log output generated by the middleware is now being sent to better stack what we're going to
Speaker A
do now is show how to consolidate the middleware in its own module so what I'm going to do is cut this out of main.py and we're going to create a new file here called middleware dop and I'm going
Speaker A
to paste the function in here and then we're going to remove The Decorator because we haven't imported the app and we can't do that which we'll show in a second because it will result in a circular depend y now I need a couple of
Speaker A
imports at the top here we need the request object from Fast API which we're using as a type hint and we also need the logger object from the logging module which we're also using in order to call methods like logger doino so we
Speaker A
now have an async function called log middleware and it lives in its own module the middleware dop module so now that we've defined this module let's go back to main. Pi and we don't need to import the request object and we need to
Speaker A
now add this middleware to our app that we have here on line five and we're not using that decorator anymore how do we register the middleware well it turns out the app object has a function called add middleware so we can use that
Speaker A
function but the problem that we have here is that that expects a middleware class and what we have in middleware DOP is a function called log middleware so let's go back to main.py and to start with let's import from middleware that
Speaker A
function that we defined called log middleware and now we need to add it to the app object but as I said it needs a class so what I'm going to do is go to this documentation or rather this issue
Speaker A
that was raised on the fast API GitHub page and the issue question here is how can you get access to the app object in a different file from main.py now if we scroll down we can get the answer to
Speaker A
this and this answer is very relevant to us it's about adding a middleware that's defined in another module of the application what we can do is we can use the base HTTP middleware class from starlet. middleware so let's bring that
Speaker A
Import in at the top here we're going to go back to main. p and just underneath our middleware import let's import the base HTTP middleware now fast API basically runs on top of a framework called Starlet and this is an async
Speaker A
framework for developing web applications and this base HTTP middleware we can go to the documentation for that so let's cross over to the Starlet documentation and what you need to do in order to implement a middle wear class that uses
Speaker A
this as its Base Class is you must override the function called dispatch and you can see that in the signal below we have a class that inherits from the base HTTP middleware and it defines a function called dispatch and then within
Speaker A
the dispatch function it defines the code for the actual middleware now what we're going to do is we're going to follow the guide on this GitHub issue we're going to pass the base HTTP middleware into the app. adds middleware
Speaker A
function and then we can pass a dispatch method and what we're going to do is we're going to set it equal to that method that we defined in the middleware dop file and that's the log middleware method so let's go back to main.py and
Speaker A
to the add middleware call on the app we're going to pass the base HTTP middleware from Starlet and then we're going to pass a dispatch function that's equal to log middleware and at the bottom we're getting this error that we
Speaker A
cannot import base HTTP middleware now we can go back to Starlet here and see what's wrong I've copied that import from this issue on GitHub that was raised in 2019 I believe the module has changed that is now starlet. middleware
Speaker A
dobas so we're going to copy base and we're going to add that into the path at the top here and if we save that and reload the server you can see it's now starting up with no issues so this is
Speaker A
just showing a way in which you can extract your middleware into its own module and then register or add that middleware in the main.py file to the app object by referencing That Base HTTP middleware now let's check that this is
Speaker A
still working if we go back to the browser and on the video upload page I'm going to refresh this and we see we get the same output if we go back to to vs code you can see that we're getting that
Speaker A
same message output as a log and that message is coming from the middleware so everything is still working but we've now managed to extract the middleware to its own file and this file can then be used basically for the roots in the
Speaker A
application now let's go back to the better stack live tail for these logs and I'm going to open this out here so we can see it better this is one of the logs that we had and it contains that
Speaker A
message where we have as the message basically some Json data all right I think this is the string version of that dictionary that we had we have a URL pointing to whatever URL generated the output and also a method but these are
Speaker A
embedded within the dictionary we might want to get these as top level Keys such as the file name or the level so that we can then search for them as in this example at the top here where we search
Speaker A
for all the logs that have a level equal to info so how do we extract this key value structure here from the message and embed those keys at the top level so they become searchable it turns out it's
Speaker A
very easy to do this let's go back to middleware dop and when we output that log dictionary what we can do is we can actually pass the dictionary in as a keyword argument called extra so I'm going to do that just now and save this
Speaker A
file and go back to one of the pages and generate these log outputs using the middleware if we then go back to better stack let's go back to the live tail that we have on the left hand side and
Speaker A
we're going to scroll right to the bottom here and when we expand that log record we see that we get the same message but the keys and values within that log output have been extracted into top level keys and values such as URL
Speaker A
here and we also have method of get here so we can then search for that for example at the top method and if we want to get only requests where the method is equal to get we can search for that and
Speaker A
it's going to return that single record because now method is a top level key it's been index by better stack and we can now search over that content and we can see the output here now you can custom imiz these records as you'd like
Speaker A
you could use Json data and Implement your own custom format or class but if you have simple keys and values that you want to appear in the top level and be searchable you can simply pass a dictionary as the extra key to the
Speaker A
logger doino warn error and so on these methods all accept this extra parameter and it allows you to pass in the custom data that you need so let's finish this video by calculating the time it takes to generate a response for each of the
Speaker A
end points in the application and we're going to do this in the middleware So within the middleware dopy file I'm going to go to the top and I'm going to import the time module that's built into Python's standard library and then right
Speaker A
at the top of the middleware function I'm going to create a variable called start and I'm going to call the time.time method that's going to give us back a time stamp at which this middleware is first invoked and remember
Speaker A
this will happen for every request that comes into the application so we have a start time and then what we do is we call this next function and await the response and that is going to give us back the response but we want to
Speaker A
calculate the time it takes in order to generate that response so we can create another variable here just below the response and that's going to be called process time and again we're going to call the time. time function here and
Speaker A
we're going to subtract the start time that we calculated at the start of this middleware function and that's going to give us back a Delta and that Delta represents the time it takes for this request to be processed and generate a
Speaker A
response now the last thing I want to do is move these calls to logger doino down below the response here so after we generate the process time let's paste that code back in here we create the log dictionary and this time I'm going to
Speaker A
add another key to that and it's going to be called process time and we're going to set that equal to the process time that we've calculated just above so that gives us our log dictionary we can then call logger doino and again we're
Speaker A
outputting that dictionary as the message but we're also passing it to the extra key in order to make those keys in the dictionary top level keys on better stack let's now save this and go back to the page for the video upload we're
Speaker A
going to refresh this and you can see we get back the response and if we do that on the main URL in the application we also get back the response we can go to the terminal and we can look at the
Speaker A
process time for these and you can see it's a very small number for that main URL and also for the video upload URL also a very small number now what we're going to do is we're going to generate
Speaker A
some artificial latency in one of these functions now when you upload a video that typically takes quite a long time so what I'm going to do at the top is I'm going to import the python async iio module this is built into Python's
Speaker A
standard library and that contains a function that you can use in an asynchronous endpoint So within the upload videos endpoint let's await asyn do sleep and we're going to sleep for 1.5 seconds we can then go back to our
Speaker A
endpoint here and I'm going to refresh this page and also go to upload videos here and you can see that that takes a little bit more time to process that request and generate the response and again if we go back to the terminal here
Speaker A
and look at the process time that's been calculated by our middleware you can see that that is basically 1.5 seconds now what I'm going to do now just to end the video is go to better stack so let's go
Speaker A
over to better Stack's UI here and go to the live tail now you might want to find the long running requests the slow requests in your application so let's now see how we can maybe do that now that we're logging out the process time
Speaker A
on every single request if we look at the record at the very bottom here you can see the process time is now a top level key here and the value is the actual time taken to process that request so we can then search the logs
Speaker A
for a process time and you can see the suggestions here better stack knows that that is a floating Point number we can then look for a processing time that's greater than 1 second and that would help us maybe diagnose very slow running
Speaker A
requests in our application so let's search for those and we get back to results and these are results for the upload videos in end point after we introduced that ASN k. sleep call and you can see the process time is now 1.49
Speaker A
seconds so we can use these search values and it doesn't need to be an equality that we use we can search for values that are greater than a number or less than a number or if it's a string
Speaker A
values that contain a substring so there are lots of options here on better stack and this is one example that you can use if you want to find slow running requests in a fast API application and similarly because we added the U to the
Speaker A
top level Keys what we can also do at the top is we can look at the URL and that's a string as it says here but we can look for URLs that contain a particular string or are equal to a
Speaker A
string so let's look for all logs at the URL upload videos and that's going to give us back all of those log outputs for that URL and again these have been generated by the middleware so that's all for this video in this video we've
Speaker A
shown how to generate a fast API application that contains a logger into instance that sends your logs to different Handler locations with a particular format and we've seen how to add a Handler for better stack and send our logs to the better stack platform
Speaker A
where you can effectively analyze them and find interesting incidents and outputs that are occurring in your application and in this video we also saw how to create a fast API middleware function that performs some kind of logic on every request response cycle in
Speaker A
your application and then in this case it's generating some log output and sending that log output to better stack where we have analyzed it and found an endpoint in our application that's running slower than we would expect we
Speaker A
can find that information and then respond to it accordingly and that's vital when you're building applications you need to know if something is performing slowly and then address that issue so thank you for watching this video if you've enjoyed the video please
Speaker A
subscribe to the better stack Channel and please give the video a thumbs up if you've enjoyed this content if you have any suggestions for similar content please let us know in the comments and we'll see you in a future video
Topics:FastAPIPython loggingmiddlewareUvicornBetter Stacklog managementasync web serverlogging formatterrequest loggingresponse logging











