2015-01-03 3 views
9

हमारे फ्लास्क ऐप द्वारा उपयोग किए जाने वाले मूल पायथन लॉगर अपवाद के बाद लॉग पर लिखना बंद कर देता है। प्रत्येक स्टॉपपेज से पहले लॉग इन की गई अंतिम प्रविष्टि अपवाद का वर्णन करने वाला एक संदेश है। आम तौर पर अगला संदेश कोड द्वारा बाद में लिखा जाता है, लेकिन लॉगजर बंद होने पर उन मामलों के लिए, after_request संदेश कभी नहीं लिखा जाता है।पायथन लॉगर बिना अपवाद अपवाद के बाद लॉगिंग बंद कर देता है

कोई विचार यह क्या हो सकता है?

नोट: मैंने मूल रूप से सर्वरफॉल्ट (https://serverfault.com/questions/655683/python-logger-stops-logging) पर यह प्रश्न पोस्ट किया था क्योंकि यह एक बुनियादी ढांचा मुद्दा था। लेकिन अब जब हमने इस मुद्दे को अपवाद के बाद घटित कर दिया है, तो यह समस्या स्टैक ओवरफ्लो के लिए बेहतर हो सकती है।

अद्यतन [2015/12/22]:

लॉगर इन्स्टेन्शियशन:

logging.addLevelName(Config.LOG_AUDIT_LEVEL_NUM, Config.LOG_AUDIT_LEVEL_NAME) 

logger = logging.getLogger(Config.LOGGER_NAME) 
logger.setLevel(Config.LOG_LEVEL) 

handler = SysLogHandler(address='/dev/log', facility=SysLogHandler.LOG_LOCAL3) 
handler.setLevel(Config.LOG_LEVEL) 

formatter = log_formatter() 
handler.setFormatter(formatter) 
logger.addHandler(handler) 

log_formatter:

class log_formatter(logging.Formatter): 

    def __init__(self, 
       fmt=None, 
       datefmt=None, 
       json_cls=None, 
       json_default=_default_json_default): 
     """ 
     :param fmt: Config as a JSON string, allowed fields; 
       extra: provide extra fields always present in logs 
       source_host: override source host name 
     :param datefmt: Date format to use (required by logging.Formatter 
      interface but not used) 
     :param json_cls: JSON encoder to forward to json.dumps 
     :param json_default: Default JSON representation for unknown types, 
          by default coerce everything to a string 
     """ 

     if fmt is not None: 
      self._fmt = json.loads(fmt) 
     else: 
      self._fmt = {} 
     self.json_default = json_default 
     self.json_cls = json_cls 

     if 'extra' not in self._fmt: 
      self.defaults = {} 
     else: 
      self.defaults = self._fmt['extra'] 

     try: 
      self.source_host = socket.gethostname() 
     except: 
      self.source_host = "" 

    def format(self, record): 
     """ 
     Format a log record to JSON, if the message is a dict 
     assume an empty message and use the dict as additional 
     fields. 
     """ 

     fields = record.__dict__.copy() 
     aux_fields = [ 
      'relativeCreated', 'process', 'args', 'module', 'funcName', 'name', 
      'thread', 'created', 'threadName', 'msecs', 'filename', 'levelno', 
      'processName', 'pathname', 'lineno', 'levelname' 
     ] 
     for k in aux_fields: 
      del fields[k] 

     if isinstance(record.msg, dict): 
      fields.update(record.msg) 
      fields.pop('msg') 
      msg = "" 
     else: 
      msg = record.getMessage() 

     if 'msg' in fields: 
      fields.pop('msg') 

     if 'exc_info' in fields: 
      if fields['exc_info']: 
       formatted = tb.format_exception(*fields['exc_info']) 
       fields['exception'] = formatted 
      fields.pop('exc_info') 

     if 'exc_text' in fields and not fields['exc_text']: 
      fields.pop('exc_text') 

     logr = self.defaults.copy() 

     logr = { 
      'timestamp': datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ'), 
      'host': self.source_host, 
     } 
     logr.update(self._build_fields(logr, fields)) 

     if msg: 
      logr['message'] = msg 

     something = json.dumps(logr, default=self.json_default, cls=self.json_cls) 
     return something 

    def _build_fields(self, defaults, fields): 
     return dict(defaults.get('fields', {}).items() + fields.items()) 

अद्यतन [2015/01/03]:

जवाब प्रश्न पोस्ट किए गए:

क्या आवेदन अभी भी अपवाद के बाद काम कर रहा है?

हां, एप्लिकेशन चल रहा है।

किस प्रकार का अपवाद उठाया गया है और इसका क्या कारण है?

आंतरिक/कस्टम अपवाद। विभिन्न प्रकार के अपवादों के कारण लॉगर बंद हो गया है।

क्या आप अपने आवेदन में धागे का उपयोग कर रहे हैं?

हां, ऐप बंदूकधारी द्वारा थ्रेड किया गया है।

लॉगिंग लाइब्रेरी का उपयोग कैसे किया जाता है?

हम डिफ़ॉल्ट FileHandler, SysLogHandler और एक कस्टम फ़ॉर्मेटर (आउटपुट JSON) का उपयोग कर रहे

यह एक फ़ाइल में लॉग ऑन करता है? क्या यह लॉग रोटेशन का उपयोग करता है?

हाँ, यह एक फ़ाइल में लॉग इन करता है, लेकिन कोई रोटेशन नहीं है।

+0

http://stackoverflow.com/help/how-to-ask - कोड के टुकड़े और क्या आप उपयोगी – dnozay

+0

@dnozay होगा की कोशिश की: कोड के टुकड़े जोड़ा। – Jason

+1

क्या आपने कभी यह हल किया है? मेरे पास एक समान मुद्दा था जब लॉग फॉर्मेटर के अंदर एक अपवाद फेंक दिया गया था (json.dumps से अनंत रिकर्सन ऑब्जेक्ट को क्रमबद्ध करने की कोशिश कर रहा है) और यह सोच रहा था कि क्या आप समाधान के साथ आए हैं। – notpeter

उत्तर

0

आपने पर्याप्त जानकारी प्रदान नहीं की है।

क्या आवेदन अभी भी अपवाद के बाद काम कर रहा है? किस प्रकार का अपवाद उठाया गया है और इसका क्या कारण है? क्या आप अपने आवेदन में धागे का उपयोग कर रहे हैं? लॉगिंग लाइब्रेरी का उपयोग कैसे किया जाता है? क्या यह एक फाइल पर लॉग ऑन करता है? क्या यह लॉग रोटेशन का उपयोग करता है?

मान लीजिए कि आप अपने आवेदन में धागे का उपयोग कर रहे हैं, स्पष्टीकरण यह है कि अपवाद थ्रेड को बंद करने का कारण बनता है, इसलिए आपको उस विशिष्ट थ्रेड से कोई गतिविधि नहीं दिखाई देगी। आपको आवेदन के साथ मुद्दों को भी ध्यान में रखना चाहिए।

यदि एप्लिकेशन अभी भी काम कर रहा है लेकिन चुप हो जाता है, तो मेरा अनुमान है कि लॉगिंग लाइब्रेरी ठीक से कॉन्फ़िगर नहीं है। जैसा कि आपने सर्वरफॉल्ट पर रिपोर्ट की है, यह समस्या फ्लेंटेंट जोड़ने के बाद दिखाई दे रही है जो आपके एप्लिकेशन लॉगिंग लाइब्रेरी का उपयोग करने के तरीके से अच्छी तरह से नहीं खेल सकता है।

+0

ने आपके प्रश्नों को मुख्य प्रश्न में उत्तर दिया। – Jason

1

after_request के संबंध में, डॉक्स से:

बोतल 0.7 इस समारोह के रूप में अनुरोध मामले में एक बिना क्रिया अपवाद घटित के अंत में निष्पादित नहीं किया जा सकता है।

और आपके लॉगिंग मुद्दे के लिए, यह हो सकता है कि आपका डीबग ध्वज सत्य पर सेट हो, जो डीबगर को लात मारने और संभवतः लॉगिंग को रोक देगा।

संदर्भ:
(http://flask.pocoo.org/docs/0.10/api/#flask.Flask.after_request)
(http://flask.pocoo.org/docs/0.10/errorhandling/#working-with-debuggers)

+0

दुर्भाग्य से हमारे पास डीबग सेट सही नहीं है। – Jason

संबंधित मुद्दे