2010-02-20 16 views
19

पर कैसे भेजा जा सकता है क्या पाइथन लॉगिंग मॉड्यूल के साथ डेब्यूजी या आईएनएफओ स्तर के साथ संदेश भेजने के लिए एक आसान तरीका है और एक उच्च स्तर के साथ अलग-अलग धाराओं में से एक है?INFO और DEBUG लॉगिंग संदेश stdout और उच्च स्तरीय संदेश को stderr

क्या यह वैसे भी एक अच्छा विचार है?

+1

एक समाधान के लिए इस देखें: http://stackoverflow.com/questions/1383254/logging-streamhandler-and-standard-streams – guettli

उत्तर

1

नहीं जरूरी एक अच्छा विचार है, लेकिन संभव है (यह जानकारी और डिबग संदेशों सामान्य उत्पादन के साथ मिश्रित! देखने के लिए भ्रामक हो सकता है) के बाद से आप एक से अधिक हैंडलर वस्तुओं और एक हो सकता है उनमें से प्रत्येक के लिए कस्टम filter, प्रत्येक हैंडलर को संभालने के लिए कौन से लॉग रिकॉर्ड चुनने और चुनने के लिए।

+1

पर है, कृपया आप दिखा सकते हैं कि (!) एक उपयुक्त फ़िल्टर कैसे जोड़ना है जो नौकरी करता है ? नीचे जीसीबी के सुझाव का अर्थ है कि "लॉगर" अभी भी stderr पर आउटपुट करता है, लेकिन "ch" stdout को एक ही चीज़ आउटपुट करता है। यह देखते हुए कि ch लॉगर पर निर्भर है, आप इसके बिना लॉगर पर फ़िल्टर कैसे सेट कर सकते हैं और फिर ch को भी लागू कर सकते हैं? उलझन में। –

6

हां। आपको अपने लॉगिंग के लिए एकाधिक हैंडलर परिभाषित करना होगा।

http://docs.python.org/library/logging.html#logging-to-multiple-destinations

http://docs.python.org/library/logging.handlers.html#module-logging.handlers

+0

मैं stdout में केवल डिबग और जानकारी संदेश और कोई चेतावनी या त्रुटि संदेश चाहते हैं । – Dinoboff

+0

दस्तावेज़ीकरण अद्यतन किया गया है, सही लिंक http://docs.python.org/library/logging.handlers.html#module-logging.handlers – gcb

3

अपडेट किए गए दस्तावेज़ों से ही, यह इस मामले को बहुत अच्छी तरह से कवर करता है।

http://docs.python.org/howto/logging.html#logging-advanced-tutorial

import sys # Add this. 
import logging 

# create logger 
logger = logging.getLogger('simple_example') 
logger.setLevel(logging.DEBUG) 

# create console handler and set level to debug 
ch = logging.StreamHandler(sys.__stdout__) # Add this 
ch.setLevel(logging.DEBUG) 

# create formatter 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 

# add formatter to ch 
ch.setFormatter(formatter) 

# add ch to logger 
logger.addHandler(ch) 

# 'application' code 
logger.debug('debug message') 
logger.info('info message') 
logger.warn('warn message') 
logger.error('error message') 
logger.critical('critical message') 

मैं टिप्पणी उदाहरण से आवश्यक दो परिवर्तन उत्पादन stdout में जाना बनाने के लिए पर उल्लेख किया है। आप स्तर के आधार पर रीडायरेक्ट करने के लिए फ़िल्टर का भी उपयोग कर सकते हैं। परिवर्तन को समझने के लिए

अधिक जानकारी http://docs.python.org/library/logging.handlers.html#module-logging.handlers

+5

यह केवल stdout पर रीडायरेक्ट करता है, लेकिन stderr के स्तर के आधार पर फ़िल्टर नहीं करता है। – guettli

+0

@guettli "आप स्तर" – gcb

+2

@gcb के आधार पर रीडायरेक्ट करने के लिए फ़िल्टर का भी उपयोग कर सकते हैं कृपया आप दिखा सकते हैं कि एक उपयुक्त फ़िल्टर कैसे जोड़ना है? आपके सुझाव का अर्थ है कि "लॉगर" अभी भी stderr पर आउटपुट करता है, लेकिन "ch" stdout पर एक ही चीज़ आउटपुट करता है। यह देखते हुए कि ch लॉगर पर निर्भर है, आप इसके बिना लॉगर पर फ़िल्टर कैसे सेट कर सकते हैं और फिर ch को भी लागू कर सकते हैं? उलझन में। –

5

पर मैं एक ही समस्या थी और एक कस्टम प्रवेश हैंडलर SplitStreamHandler बुलाया लिखा है:

import sys 
import logging 

class SplitStreamHandler(logging.Handler): 
    def __init__(self): 
     logging.Handler.__init__(self) 

    def emit(self, record): 
     # mostly copy-paste from logging.StreamHandler 
     try: 
      msg = self.format(record) 
      if record.levelno < logging.WARNING: 
       stream = sys.stdout 
      else: 
       stream = sys.stderr 
      fs = "%s\n" 

      try: 
       if (isinstance(msg, unicode) and 
        getattr(stream, 'encoding', None)): 
        ufs = fs.decode(stream.encoding) 
        try: 
         stream.write(ufs % msg) 
        except UnicodeEncodeError: 
         stream.write((ufs % msg).encode(stream.encoding)) 
       else: 
        stream.write(fs % msg) 
      except UnicodeError: 
       stream.write(fs % msg.encode("UTF-8")) 

      stream.flush() 
     except (KeyboardInterrupt, SystemExit): 
      raise 
     except: 
      self.handleError(record) 
+0

मुझे पता है कि यह थोड़ा ऑफ-विषय है, लेकिन क्या कोई चरित्र एन्कोडिंग के संदर्भ में एन्कोड/डीकोड कोशिश/पकड़ तर्क को समझा सकता है? – Chris

19
import logging 
import sys 

class LessThanFilter(logging.Filter): 
    def __init__(self, exclusive_maximum, name=""): 
     super(LessThanFilter, self).__init__(name) 
     self.max_level = exclusive_maximum 

    def filter(self, record): 
     #non-zero return means we log this message 
     return 1 if record.levelno < self.max_level else 0 

#Get the root logger 
logger = logging.getLogger() 
#Have to set the root logger level, it defaults to logging.WARNING 
logger.setLevel(logging.NOTSET) 

logging_handler_out = logging.StreamHandler(sys.stdout) 
logging_handler_out.setLevel(logging.DEBUG) 
logging_handler_out.addFilter(LessThanFilter(logging.WARNING)) 
logger.addHandler(logging_handler_out) 

logging_handler_err = logging.StreamHandler(sys.stderr) 
logging_handler_err.setLevel(logging.WARNING) 
logger.addHandler(logging_handler_err) 

#demonstrate the logging levels 
logger.debug('DEBUG') 
logger.info('INFO') 
logger.warning('WARNING') 
logger.error('ERROR') 
logger.critical('CRITICAL') 

कार्यान्वयन अलग रूप में, मैं यह है लगता है टर्मिनल पर आउटपुट के लिए पायथन में लॉगिंग सुविधाओं का उपयोग करना एक अच्छा विचार है, विशेष रूप से क्योंकि आप फ़ाइल में अतिरिक्त लॉग इन करने के लिए एक और हैंडलर जोड़ सकते हैं। यदि आप DEBUG के बजाय STDout INFO होने के लिए सेट करते हैं, तो आप अतिरिक्त DEBUG जानकारी भी शामिल कर सकते हैं जिसे उपयोगकर्ता लॉग फ़ाइल में मानक रूप से नहीं देख पाएगा।

+0

आपको 'LessThanFilter' कक्षा कहां से मिलता है। इसे Python3 libs में नहीं मिल रहा है। – buhtz

+2

मैंने इसे लिखा (और कार्यान्वयन प्रदान किया), यह मानक पुस्तकालयों में नहीं है। –

+0

बहुत बहुत धन्यवाद। यह पहली जगह है जिसे मैंने किसी को चेतावनी के डिफ़ॉल्ट लॉगिंग स्तर का उल्लेख किया है। मैं इस दिन एक दिन खो दिया। संतिया के लिए कुछ समानता बहाल की जाती है। धन्यवाद! – penderi

-1
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
import logging 
import sys 

class LessThenFilter(logging.Filter): 
    def __init__(self, level): 
     self._level = level 
     logging.Filter.__init__(self) 

    def filter(self, rec): 
     return rec.levelno < self._level 

log = logging.getLogger() 
log.setLevel(logging.NOTSET) 

sh_out = logging.StreamHandler(stream=sys.stdout) 
sh_out.setLevel(logging.DEBUG) 
sh_out.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) 
sh_out.addFilter(LessThenFilter(logging.WARNING)) 
log.addHandler(sh_out) 

sh_err = logging.StreamHandler(stream=sys.stderr) 
sh_err.setLevel(logging.WARNING) 
sh_err.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) 
log.addHandler(sh_err) 

logging.critical('x') 
logging.error('x') 
logging.warning('x') 
logging.info('x') 
logging.debug('x') 
संबंधित मुद्दे