2015-01-05 5 views
10

करने के लिए अतिरिक्त जानकारी प्रदान करें बोतल 0.10 के लिए default debug log formatमैं इसे कैसे यह करने के लिए बदल सकता हूँ बोतल के app.logger

debug_log_format = 
'-------------------------------------------------------------------------\n% 
%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s 
\n-------------------------------------------------------------------------' 

है:

'-------------------------------------------------------------------------\n% 
work_id %(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s 
\n-------------------------------------------------------------------------' 

जहां work_id प्रत्येक अनुरोध के लिए यादृच्छिक रूप से जनरेट UUID है।

तो लकड़हारा अपने आप द्वारा बनाई गई है, मैं सिर्फ एक logging.LoggerAdapter का उपयोग करें और एक dict {'work_id': some_uuid} के रूप में अतिरिक्त जानकारी प्रदान कर सकते, तो मैं यह लॉग रिकॉर्ड में record.work_id का उपयोग कर पहुँच सकते हैं।

लेकिन app.loggercreate_logger() in Flask'slogging.py द्वारा बनाया गया है, क्या मुझे इच्छित चीज़ों को प्राप्त करने के लिए फ्लास्क स्रोत को संशोधित करना है?

मैंने सोचा कि app.logger को अपने स्वयं के लॉगर के साथ ओवरराइड करें, जैसे app.logger = my_logger, यह सही नहीं लगता है।

उत्तर

8

वाया Flask.debug_log_format

बस इस कार्य करें:

app.debug = True 
app.debug_log_format = """------------------------------------------------------------------------- 
%(worker_id)s (levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s 
-------------------------------------------------------------------------""" 
app.logger.log("test", extra={"worker_id": request.your_uuid_property) 

उदाहरण:

import logging 
from flask import Flask, request 
app = Flask(__name__) 

# please replace "request.uuid" with your actual property 
log = lambda msg: app.logger.info(msg, extra={'worker_id': "request.uuid" }) 

@app.route("/") 
def hello(): 
    log("hello world") 
    return "Hello World!" 

if __name__ == "__main__": 
    app.debug_log_format = """------------------------------------------------------------------------- 
    %(worker_id)s in %(module)s [%(pathname)s:%(lineno)d]: 
    %(message)s 
    -------------------------------------------------------------------------""" 
    app.debug = True 
    log("hello world") 
    app.run() 

वाया हैंडलर और मानक प्रवेश मॉड्यूल के फ़ॉर्मेटर

फ्लास्क किसी भी तरह से लॉगिंग का उपयोग करता है, ताकि आप बाहर फ्लास्क प्राप्त करने के लिए logging.Handler और logging.Formatter का उपयोग कर सकें। एक सामान्य उदाहरण here पाया जा सकता है। लॉगिंग विन्यास की उन्नत विषय the doc में पाया जा सकता है और cookbook

अपने प्रश्न के बारे में आपको एक बेहतर उदाहरण में है:

import logging 
from flask import Flask 
app = Flask(__name__) 

class CustomFormatter(logging.Formatter): 
    def format(self, record): 
     record.worker_id = "request.uuid" # replace this with your variable 
     return super(CustomFormatter,self).format(record) 

@app.route("/") 
def hello(): 
    app.logger.info("hello world") 
    return "Hello World!" 

if __name__ == "__main__": 
    custom_format = """------------------------------------------------------------------------- 
    %(worker_id)s in %(module)s [%(pathname)s:%(lineno)d]: 
    %(message)s 
    -------------------------------------------------------------------------""" 
    app.debug = True 
    ch = logging.StreamHandler() 
    ch.setFormatter(CustomFormatter(fmt=custom_format)) 
    app.logger.addHandler(ch) 
    app.logger.debug("hello world") 
    app.run() 

वाया अधिभावी logging.Logger वर्ग

एक ही उद्देश्य हो सकता है डिफ़ॉल्ट लॉगर वर्ग को ओवरराइड करके हासिल किया गया। संयोजन flask request context stack, आप लॉग में अपने स्वयं के क्षेत्र प्राप्त करने में सक्षम हो जाएगा:

import logging 
from flask import Flask 
app = Flask(__name__) 
from flask import _request_ctx_stack 

CUSTOM_FORMAT = """------------------------------------------------------------------------- 
%(worker_id)s in %(module)s [%(pathname)s:%(lineno)d]: 
%(message)s 
-------------------------------------------------------------------------""" 

class MyLogger(logging.Logger): 
    def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None): 
     ctx = _request_ctx_stack.top 
     custom_extra = dict(
      worker_id="request.uuid" 
     ) 
     if ctx is not None: 
      url = ctx.request.url # please replace this with your own field 
      custom_extra["worker_id"] = url 

     if extra is not None: 
      extra.update(custom_extra) 
     else: 
      extra = custom_extra 
     return super(MyLogger,self).makeRecord(name, level, fn, lno, msg, args, exc_info, func=func, extra=extra) 

logging.setLoggerClass(MyLogger) 

@app.route("/") 
def hello(): 
    app.logger.info("hello world") 
    return "Hello World!" 

if __name__ == "__main__": 
    app.debug_log_format = CUSTOM_FORMAT 
    app.debug = True 
    app.logger.debug("hello world") 
    app.run() 
+0

मैं कैसे रिकॉर्ड लॉग इन करने के 'work_id' पारित करते हैं, क्योंकि रिकॉर्ड रिकॉर्ड करने के लिए इसे पास किए बिना, फॉर्मेटर इसे एक्सेस नहीं कर सकता है, जिसका अर्थ है कि आपका पहला समाधान बिल्कुल काम नहीं करता है। –

+0

@NotanID कृपया मेरे अपडेट देखें। – chfw

+0

यह काम करेगा। लेकिन मैं सीधे 'app.logger' को संशोधित करने का एक तरीका ढूंढ रहा हूं, इसलिए मुझे इन लिपटे लॉग कार्यों को ग्लोबल्स के रूप में आयात करने की आवश्यकता नहीं है।वैसे भी धन्यवाद :) –

1

यहाँ एक कस्टम Formatter का उपयोग कर एक और उदाहरण है। धन्यवाद @chfw करने और this

को मैं यहाँ flask.has_request_context() के उपयोग की तरह है, ताकि प्रवेश इकाई के रास्ते में नहीं मिलता है परीक्षण

 
import logging 
from logging import StreamHandler 
import flask 
from flask import Flask, g, request 

logger = logging.getLogger(__name__) 
logger.setLevel(logging.DEBUG) 
app = flask.Flask(__name__) 


class CustomFormatter(logging.Formatter): 
    def format(self, record): 
     record.uuid = None 
     if flask.has_request_context(): 
      record.uuid = g.uuid if hasattr(g, 'uuid') else None 
      record.path = request.path 
      record.endpoint = request.endpoint 
      record.remote_addr = request.remote_addr 
     return super(CustomFormatter, self).format(record) 

custom_format = '''%(levelname)s %(name)s %(uuid)s %(path)s %(endpoint)s %(remote_addr)s %(message)s''' 
handler = StreamHandler() 
handler.setFormatter(CustomFormatter(fmt=custom_format)) 
logger.addHandler(handler) 


with app.test_request_context(): 
    g.uuid = 'foo' 
    logger.fatal('help') 
संबंधित मुद्दे