I have a Python Flask application, the entry file configures a logger on the app, like so:
app = Flask(__name__)
handler = logging.StreamHandler(sys.stdout)
app.logger.addHandler(handler)
app.logger.setLevel(logging.DEBUG)
I then do a bunch of logging using
app.logger.debug("Log Message")
which works fine. However, I have a few API functions like:
@app.route('/api/my-stuff', methods=['GET'])
def get_my_stuff():
db_manager = get_manager()
query = create_query(request.args)
service = Service(db_manager, query)
app.logger.debug("Req: {}".format(request.url))
What I would like to know is how can I do logging within that Service
module/python class. Do I have to pass the app to it? That seems like a bad practice, but I don't know how to get a handle to the app.logger from outside of the main Flask file...
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.
Werkzeug is a comprehensive WSGI web application library. It began as a simple collection of various utilities for WSGI applications and has become one of the most advanced WSGI utility libraries. Werkzeug doesn't enforce any dependencies.
log” will be created inside your Flask application folder.
Even though this is a possible duplicate I want to write out a tiny bit of python logging knowledge.
DON'T pass loggers around. You can always access any given logger by logging.getLogger(<log name as string>)
. By default it looks like* flask uses the name you provide to the Flask
class.
So if your main module is called 'my_tool', you would want to do logger = logging.getLogger('my_tool')
in the Service
module.
To add onto that, I like to be explicit about naming my loggers and packages, so I would do Flask('my_tool')
** and in other modules, have sub level loggers like. logger = logging.getLogger('my_tool.services')
that all use the same root logger (and handlers).
* No experience, based off other answer.
** Again, don't use flask, dk if that is good practice
Edit: Super simple stupid example
Main Flask app
import sys
import logging
import flask
from module2 import hi
app = flask.Flask('tester')
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
app.logger.addHandler(handler)
app.logger.setLevel(logging.DEBUG)
@app.route("/index")
def index():
app.logger.debug("TESTING!")
hi()
return "hi"
if __name__ == '__main__':
app.run()
module2
import logging
log = logging.getLogger('tester.sub')
def hi():
log.warning('warning test')
Outputs
127.0.0.1 - - [04/Oct/2016 20:08:29] "GET /index HTTP/1.1" 200 -
2016-10-04 20:08:29,098 - tester - DEBUG - TESTING!
2016-10-04 20:08:29,098 - tester.sub - WARNING - warning test
Edit 2: Messing with subloggers
Totally unneeded, just for general knowledge.
By defining a child logger, done by adding a .something
after the root logger name in logging.getLogger('root.something')
it gives you basiclly a different namespace to work with.
I personally like using it to group functionality in logging. So have some .tool
or .db
to know what type of code is logging. But it also allows so that those child loggers can have their own handlers. So if you only want some of your code to print to stderr
, or to a log you can do so. Here is an example with a modified module2
.
module2
import logging
import sys
log = logging.getLogger('tester.sub')
handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(logging.Formatter('%(name)s - %(levelname)s - %(message)s'))
log.addHandler(handler)
log.setLevel(logging.INFO)
def hi():
log.warning("test")
Output
127.0.0.1 - - [04/Oct/2016 20:23:18] "GET /index HTTP/1.1" 200 -
2016-10-04 20:23:18,354 - tester - DEBUG - TESTING!
tester.sub - WARNING - test
2016-10-04 20:23:18,354 - tester.sub - WARNING - test
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