3

Webアプリケーションにcherrypy(WSGIを提供する)付きのボトルを使用しています。このセットアップでは、CherryPy は Web アクセスをログに記録しません。現在、次のように、ボトルのフック プラグインを使用してほとんどすべてをログに記録しています。

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 であることを除いて、これはほぼ正しいです。ボトルは、cherrypy によって返される content-length を認識していないようです。これは正しい評価ですか? さらに重要なことに、ログに記録できるように取得する方法はありますか?

bottle と cherrypy を使用してアクセス ログを取得するより良い方法を受け入れます。

ありがとう!

4

2 に答える 2

5

いくつかのアプローチを考えることができますが、これが最善だと思うものです: ミドルウェア アプリを使用してリクエストをログに記録します。

質問のコードに基づく完全な例を次に示します。(私は変更していません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)

これでうまくいくはずです。そうでない場合は、お知らせください。お手伝いします。

于 2013-07-24T03:19:34.360 に答える