使用bottle和cherrypy记录响应内容长度

时间:2013-07-23 22:10:18

标签: python logging cherrypy bottle content-length

我正在使用带有cherrypy(提供WSGI)的瓶子用于Web应用程序。 CherryPy不会在此设置中记录Web访问。目前,我几乎使用瓶子hook plug-in记录所有内容,如下所示:

import bottle
from bottle import route, static_file, get, post, error, request, template, redirect, response, hook

@hook('after_request')
def log_after_request():
    try:
        length = response.content_length
    except:
        try:
            length = len(response.body)
        except:
            length = '???'
    print '{ip} - - [{time}] "{method} {uri} {protocol}" {status} {length}'.format(
        ip=request.environ.get('REMOTE_ADDR'),
        time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        method=request.environ.get('REQUEST_METHOD'),
        uri=request.environ.get('REQUEST_URI'),
        protocol=request.environ.get('SERVER_PROTOCOL'),
        status=response.status_code,
        length=length,
    )

@route('/index.html')
def index_handler():
    return '<h1>Hello, world!</h1>'

app = bottle.default_app()
bottle.run(host='0.0.0.0', port='80', app=app, server='cherrypy', request_queue_size=300, debug=True)

这为STDOUT提供了日志条目,如下所示:

192.168.1.1 - - [2013-07-23 17:04:04] "GET /index.html HTTP/1.1" 200 0

这几乎是正确的,除了内容长度始终为0.看起来瓶子不知道cherrypy返回的内容长度。这是一个正确的评估,更重要的是,有没有办法检索它,所以我可以记录它?

我愿意采用更好的方法来获取使用bottle和cherrypy的访问日志记录。

谢谢!

2 个答案:

答案 0 :(得分:4)

我可以想到几种方法,但这是我认为最好的方法:使用中间件应用来记录请求。

以下是基于您问题中的代码的完整示例。 (我没有更改log_after_request;大部分操作都在AccessLogMiddleware.__call__

import datetime
import bottle
from bottle import route, static_file, get, post, error, request, template, redirect, response, hook

# unchanged from OP
@route('/index.html')
def index_handler():
    return '<h1>Hello, world!</h1>'

# unchanged from OP
def log_after_request():
    try:
        length = response.content_length
    except:
        try:
            length = len(response.body)
        except:
            length = '???'
    print 'MYLOG:', '{ip} - - [{time}] "{method} {uri} {protocol}" {status} {length}'.format(
        ip=request.environ.get('REMOTE_ADDR'),
        time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        method=request.environ.get('REQUEST_METHOD'),
        uri=request.environ.get('REQUEST_URI'),
        protocol=request.environ.get('SERVER_PROTOCOL'),
        status=response.status_code,
        length=length,
    )

# code I've added begins here
class AccessLogMiddleware(object):
    def __init__(self, app):
        self.app = app

    def __call__(self, e, h):
        # call bottle and store the return value
        ret_val = self.app(e, h)

        # log the request
        log_after_request()

        # return bottle's return value
        return ret_val


app = bottle.app()
logged_app = AccessLogMiddleware(app)
bottle.run(host='0.0.0.0', port='8000', app=logged_app)

应该这样做;如果没有,请告诉我,我会帮忙。

答案 1 :(得分:1)

当您更新到尚未正式发布的Bottle 0.13-dev分支时,原始问题中的代码现在可以使用。最新发布的稳定的0.12.18分支仍然存在此错误,并且对于响应内容的长度仍将返回0。

更新为0.13(您可以在此处获取:https://github.com/bottlepy/bottle)后,该代码即可正常工作。