2013-07-23 3 views
2

Я использую бутылку с черригой (которая предоставляет WSGI) для веб-приложения. CherryPy не регистрирует веб-доступ в этой настройке. В настоящее время я почти регистрации все, используя бутылку 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. Является ли это правильной оценкой и, что более важно, есть способ ее получить, поэтому я могу ее зарегистрировать?

Я открыт для лучших способов получить доступ к каротажу с использованием бутылки и вишневого дерева.

Спасибо!

ответ

3

Я могу придумать несколько подходов, но вот тот, который я считаю лучшим: используйте приложение промежуточного программного обеспечения для регистрации запросов.

Вот полный пример, основанный на коде в вашем вопросе. (Я не изменил 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

Это сработало, но ваше решение по существу дублирует подключаемый модуль крюка для бутылок, за исключением того, что объект ответа имеет допустимую длину содержимого. Это заставляет задуматься, есть ли ошибка в подключении плагина к бутылке. – Trevor

+0

Согласовано. FWIW, я действительно думаю, что метод обертывания/расслоения более изящный, чем использование крючка бутылки, даже если крючок работает так, как ожидалось. В любом случае, счастлив, что это сработало! –

Смежные вопросы