2016-09-27 74 views
1

我有,這些會用來象一個REST API實現許多方法這樣的小瓶的應用:如何使用燒瓶中的請求信息來豐富日誌消息?

@route('/do/something', methods=['POST']) 
def something(): 
    app.logger.debug("got request to /do/something") 
    result = something_implementation(request.json()) 
    app.logger.debug("result was %s", str(result)) 
    return flask.Response(result) 

我想與從請求對象信息自動豐富這些日誌信息如頭信息,零件的身體和其他任何方便。

我如何以優雅和pythonic的方式做到這一點?

當然,我可以在我自己的函數中包裝app.logger,並將請求對象和消息一起傳遞,但必須有更好更簡單的方法。

回答

1

我已經通過繼承logging.Filter並將其添加到我的處理程序解決了這個。

事情是這樣的:

class ContextFilter(logging.Filter): 
    '''Enhances log messages with contextual information''' 
    def filter(self, record): 
     try: 
      record.rid = request.rid 
     except RuntimeError as exc: 
      if str(exc.message) == 'working outside of request context': 
       record.rid = '' 
      else: 
       raise exc 
     return True 

在try/except子句是必要的日誌信息工作的請求上下文之外。 然後用它是這樣的:

fileHandler = RotatingFileHandler(app.config['LOGFILE'], maxBytes=20971520, 
            backupCount=5, encoding='utf-8') 
fileHandler.setLevel(logging.DEBUG) 
fileHandler.addFilter(ContextFilter()) 
filefmt = '%(asctime)s [%(filename)s:%(lineno)d] %(rid)s: %(message)s' 
fileFormatter = logging.Formatter(filefmt) 
fileHandler.setFormatter(fileFormatter) 
app.logger.addHandler(fileHandler) 

在未來,我可以在ContextFilter.filter()方法添加更多的字段,並使用它們,但是我請格式化配置。

2

我通常包括我app.py文件這樣的事情記錄調試信息對於每個請求,以處理標準誤差一起:

# Useful debugging interceptor to log all values posted to the endpoint 
@app.before_request 
def before(): 
    values = 'values: ' 
    if len(request.values) == 0: 
     values += '(None)' 
    for key in request.values: 
     values += key + ': ' + request.values[key] + ', ' 
    app.logger.debug(values) 

# Useful debugging interceptor to log all endpoint responses 
@app.after_request 
def after(response): 
    app.logger.debug('response: ' + response.status + ', ' + response.data.decode('utf-8')) 
    return response 

# Default handler for uncaught exceptions in the app 
@app.errorhandler(500) 
def internal_error(exception): 
    app.logger.error(exception) 
    return flask.make_response('server error', 500) 

# Default handler for all bad requests sent to the app 
@app.errorhandler(400) 
def handle_bad_request(e): 
    app.logger.info('Bad request', e) 
    return flask.make_response('bad request', 400)v 
+1

謝謝。我已經有了類似的東西,但這還不夠,我需要記錄處理請求時發生了什麼。看起來我需要實現一個自定義過濾器:https://docs.python.org/2/howto/logging-cookbook.html#using-filters-to-impart-contextual-information 我只需要找出如何從此過濾器訪問當前的請求上下文。 – Patrick