我正在使用带有Cherrypy(提供WSGI)的瓶子用于Web应用程序. CherryPy在此设置中不记录Web访问.目前,我几乎使用bottle 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
这几乎是正确的,除了content-length始终为0.似乎bottle不知道cherrypy返回的content-length.这是正确的评估吗?更重要的是,有没有办法找回它,所以我可以将其记录下来?
我愿意使用更好的方法来使用bottle和cherrypy获取访问日志.
谢谢!
解决方法:
我可以想到几种方法,但是我认为这是最好的一种方法:使用中间件应用程序记录请求.
这是一个基于您问题中代码的完整示例. (我没有更改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)
这应该够了吧;如果没有,请告诉我,我会帮忙.