In this topic, we will discuss the way we log our data. It's a good thing to know because some errors are difficult to track down just by looking at the code. Provided that you have a log of all queries and their results (code and decryption), it takes no pain to do it. Let's start!
Simple logging
First things first — we need to create an application that stores our requests. For this, we need to import the necessary objects:
from flask import request
from flask import make_response
from flask import Flask
import datetime as dtWe also import the datetime module. It allows us to get the current time and date. Next, let's create a function that will log our information to a .txt file:
def log(*args):
text = ' '.join([str(element) for element in args])
with open('log.txt', 'a') as log_file:
log_file.write(text + '\n')We refer to *args here to store an unlimited number of positional arguments to the args variable (yes, args is the variable name, and we can change it to any other). We will use it as a container for all information we want to log. Of course, we can log data directly in the view function, but using a separate function is considered good coding practice. The next step is familiar to us: we need to create a standard web application:
app = Flask('main')
@app.route('/no-content')
def no_data():
response = make_response('Hello there!', 204)
return response
@app.route('/some-content')
def data():
response = make_response('Hello there! There are data!', 200)
return responseWe've defined two view functions, and now, it's time for something new! Let's create a function that will log every request that our server receives. We can do this by using the decorator @app.after_request. As the name indicates, the following function is executed after every request. This is a neat device if we need to create a callback function. There are more decorators like this, such as @app.before_request and @app.before_first_request. You can find them in the Official documentation.
@app.after_request
def after_request(response):
log(dt.datetime.now(),
request.remote_addr,
request.method,
request.scheme,
request.full_path,
response.status
)
return responseThis function receives the response and transfers its content to the log function:
| Displays the client remote address |
| Displays a request method |
| Shows a request HTTP scheme |
| Shows full URL to a certain web app or site |
| Shows the request status code |
This information is passed to the log function and to the log file!
To see that it works, let's start our app and make requests to it. In the console, the server displays the requests in the following form:
If we open log.txt, we will find a lot of different requests there. You can configure logging by adjusting the log function:
Our logging works! We've created a function to store the records of our server. There are also more advanced ways to logging. Let's figure them out!
Advanced logging
In this part of the topic, we will talk about a very cool module called logging. It can log our information quickly and conveniently — we need to write one code line; it will log whatever we want! First, we need to understand the urgency hierarchy. There are 5 urgency levels: DEBUG, INFO, WARNING, ERROR, and CRITICAL. The CRITICAL messages are of most importance, while DEBUG is less important. We import the logging library and configure the logging options:
import logging
logging.basicConfig(filename='app.txt', level=logging.DEBUG)We've specified the filename of the log file and the logging level. Now, we are ready to log!
logging.info('This is just information message')
logging.warning('This is some warning message')
logging.error('This is quite severe message')
logging.critical('This is a very severe message. Please, take some actions')When we open the file, we will see something like this:
We can log any information we need just by selecting different urgency levels. Depending on the task, you can log only the most important notifications, or, for example, errors for debugging or info messages for checking whether the information has reached the users and processed, and so on.
Conclusion
In this topic, we've discussed basic and advanced logging. We can now effectively receive and save messages, requests, errors, and many more. Good luck with your study!