I have a simple Flask app like this:
from flask import Flask
import util
APP = Flask("app")
APP.debug = True
@APP.route('/', methods=['GET'])
def index():
APP.logger.info("info message from index")
util.test()
return "hello world"
if __name__ == '__main__':
APP.run()
Where the util module is:
import logging
logger = logging.getLogger(__name__)
def test():
logger.info("info message from util")
When I run only "info message from index" appears in the console.
What is the simplest way to get the two logging messages to print to the console together, and to also both print to a log file together.
I've tried various approaches and none have worked for me. In particular the util one never shows up.
To start with logging in Flask, first import the logging module from Python. This logger module comes out of the box from the Python installation and does not need configuration. The Python logging module logs events based on pre-defined levels. The recorded log events are known as log records.
Files named __init__.py are used to mark directories on disk as Python package directories. So it really depends on your structure of projects. Ideally if you have a project with multiple folders, you might have to make them as python package directories.
As we would like to display all logs immediately, we have to configure the proxy server to stop buffering them. Configuring Nginx can be done in 2 steps: 1) create a . ebextensions folder in your project's root folder, 2) add a config file to this folder (it doesn't matter what it's name is, as long as it has a .
The @ is telling Python to decorate the function index() with the decorator defined in app. route() . Basically, a decorator is a function that modifies the behaviour of another function. As a toy example, consider this.
Use current_app
to access the app's logger:
from flask import current_app
def test():
current_app.logger.info("info message from util")
This allow you to use the default Flask logger.
More information: http://flask.pocoo.org/docs/logging/
The logger in util
doesn't generate output because Python logging is set to log warnings and higher by default, and info is lower than warning. Configure Python's logging with the level and handlers you want.
If logging isn't configured, Flask adds a handler for its own logger and sets the level to debug in debug mode, which is why the app.logger
message shows up. Flask's docs show how to configure logging the way it does and other examples.
from logging.config import dictConfig
dictConfig({
'version': 1,
'formatters': {'default': {
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
}},
'handlers': {'wsgi': {
'class': 'logging.StreamHandler',
'stream': 'ext://flask.logging.wsgi_errors_stream',
'formatter': 'default'
}},
'root': {
'level': 'INFO',
'handlers': ['wsgi']
}
})
app = Flask(__name__)
from project import util
util.test()
If you import util
before calling dictConfig
, you'll notice that the logging still doesn't work. This is because Python will disable existing loggers when configuring. You can prevent that by adding 'disable_existing_loggers': False
to the config, but this comes with the tradeoff that you might see duplicate logs if a logger was already configured. Alternatively, don't get logger
at the module level, get it inside the function when it's needed.
If you specifically want to use the app's logger elsewhere, you need to import the app. Since this is prone to circular import errors, or even impossible when using an app factory, use current_app
instead to access the app during requests.
from flask import current_app
def test():
current_app.logger.info('info message from util')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With