Reputation: 652
I'm trying to log the request body of an incoming post request and persist it across all modules being called in the function thereafter. Here's an example of what I'm trying to achieve:
main_app.py
from flask import Flask
from other_file import other_module
import logging
FORMAT = '%(request_body_id)s- %(message)s'
logging.basicConfig(format=FORMAT)
log = logging.getLogger('test_logger')
@app.route('/', methods=['POST'])
def test_function():
log = logging.LoggerAdapter(log, {'request_body_id': request.body['id']})
log.info("My message")
other_module()
return "foo"
other_file.py
log = logging.getLogger('test_logger')
def other_module():
log.info("My second message")
What I'm looking for is:
>>> INFO 123456- My message
>>> INFO 123456- My second message
What I get is:
>>> INFO 123456- My message
>>> INFO - My second message
Update: Passing the request body as a parameter to other_module is not an option as there are tonnes of modules being called in the real case that need to output the request source.
Upvotes: 2
Views: 3471
Reputation: 11223
You can add any additional data into log using logging.Formatter. Just an example:
log.py
import logging
from flask import request
class __RequestFormatter(logging.Formatter):
def format(self, record):
# you can set here everything what you need
# I just added url and id from GET parameter
record.id = request.args.get('id')
record.url = request.url
return super().format(record)
# format of our log record.
# print url and id of record which was set in format()
__stream_handler = logging.StreamHandler()
__stream_handler.setFormatter(__RequestFormatter(
'[%(asctime)s %(levelname)s] requested: %(url)s, id: %(id)s in %(module)s: %(message)s'
))
logger = logging.getLogger('my_loger')
logger.setLevel(logging.INFO)
logger.addHandler(__stream_handler)
app.py
from flask import Flask
from log import logger
from other_file import other_module
app = Flask(__name__)
@app.route('/test')
def test():
logger.info('/test was called')
other_module()
return 'hi'
other_file.py
from log import logger
def other_module():
logger.info("My second message")
Now let's call /test?id=example_id
, /test?id=example_id2
and check logs:
[2018-09-28 17:40:48,669 INFO] requested: http://127.0.0.1:5000/test?id=example_id, id: example_id in app: /test was called
[2018-09-28 17:40:48,670 INFO] requested: http://127.0.0.1:5000/test?id=example_id, id: example_id in other_file: My second message
[2018-09-28 17:40:51,475 INFO] requested: http://127.0.0.1:5000/test?id=example_id2, id: example_id2 in app: /test was called
[2018-09-28 17:40:51,476 INFO] requested: http://127.0.0.1:5000/test?id=example_id2, id: example_id2 in other_file: My second message
As you can see all messages include id
of request. So you can use Formatter
to customize everything what you need. Also you can try to use flask-log-request-id.
Hope this helps.
Upvotes: 1