Reputation: 1931
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.
Upvotes: 13
Views: 6909
Reputation: 127410
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')
Upvotes: 5
Reputation: 3005
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/
Upvotes: 12