Python Novice Python Novice - 1 year ago 127
HTTP Question

How do I customize Tornado's access logs

I have a Flask app that is being run through Tornado:

import os
import logging
import sys
from flask import Flask, request, jsonify
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop

app = Flask(__name__)

@app.route("/test", methods=["GET"])
def healthz():
return jsonify(message="OK!"), 200

def not_found(error):

return jsonify(error="Requested page does not exist."), 404

def run_app():

http_server = HTTPServer(WSGIContainer(app))

if __name__ == '__main__':

logFormat = "timestamp=%(asctime)s pid=%(process)d loglevel=%(levelname)s %(message)s"


I am using a custom log and getting output like this:

timestamp=2016-11-05 12:26:39,287 pid=23356 loglevel=INFO 200 GET /test ( 0.63ms
timestamp=2016-11-05 12:26:10,306 pid=23356 loglevel=WARNING 404 GET / ( 0.67ms

How do I modify Tornado's access log to display like this:

status_code=200 method=GET URL=/test ip= duration=0.63ms

So that I end up with this in stdout:

timestamp=2016-11-05 12:26:10,306 pid=23356 loglevel=INFO status_code=200 method=GET URL=/test ip= duration=0.63ms

Answer Source

I'd override the WSGIContainer's log function:

from tornado.log import access_log
from tornado.wsgi import WSGIContainer

class MyWSGI(WSGIContainer):
    def _log(self, status_code, request):
        if status_code < 400:
            log_method =
        elif status_code < 500:
            log_method = access_log.warning
            log_method = access_log.error

        request_time = 1000.0 * request.request_time()
            "status_code=%s method=%s URL=%s ip=%s duration=%.2fms",
            status_code, request.method,
            request.uri, request.remote_ip, request_time)

Then use MyWSGI in place of WSGIContainer.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download