2016-10-17 8 views
8

मेरे पास लॉगिंग का उपयोग कर टीसीपी पर एक syslog सर्वर पर लॉग भेजने की प्रक्रिया है। SyslogHandler। दुर्भाग्यवश, यदि किसी कारण से syslog सर्वर पुनरारंभ किया गया है, तो प्रक्रिया लॉग भेजने को रोकती है और कनेक्शन को पुन: स्थापित करने में असमर्थ है।टीसीपी पर पाइथन SysLogHandler: कनेक्शन हानि को संभालने

मैं सोच रहा था कि क्या कोई इस व्यवहार को दूर करने और लॉगिंग को मजबूर करने के तरीके के बारे में जानता है। कनेक्शन लॉग को फिर से स्थापित करने के लिए।

import logging 
import logging.handlers 
import logging.config 

logging.config.fileConfig('logging.cfg') 
logging.debug("debug log message") 

logging.cfg:

[loggers] 
keys=root,remote 

[handlers] 
keys=local,remote 

[logger_remote] 
qualname=remote 
level=INFO 
handlers=remote 

[logger_root] 
qualname=root 
level=DEBUG 
handlers=local 

[handler_local] 
class=handlers.StreamHandler 
level=DEBUG 
formatter=local 
args=(sys.stdout,) 

[handler_remote] 
class=handlers.SysLogHandler 
level=DEBUG 
formatter=remote 
args=(('localhost', 514), handlers.SysLogHandler.LOG_USER, 1) 

[formatters] 
keys=local,remote 

[formatter_local] 
format=%(module)s %(levelname)s %(message)s 

[formatter_remote] 
format=%(asctime)s %(message)s 

त्रुटि मैं syslog सर्वर पुनरारंभ के बाद मिलती रहती है:

हैंडलर का उपयोग करना

कोड की तरह कुछ होगा

Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/logging/handlers.py", line 866, in emit 
    self.socket.sendall(msg) 
    File "/usr/local/lib/python2.7/socket.py", line 228, in meth 
    return getattr(self._sock,name)(*args) 
error: [Errno 32] Broken pipe 

मैं किसी भी अंतर्दृष्टि की सराहना करता हूं। धन्यवाद!

+0

'('स्थानीय होस्ट', 514)' मतलब है "नमस्ते, मेरा जड़ दोस्त आप कौन आपको करने के लिए कहा 514 पोर्ट का उपयोग कर सकते हैं कि कर रहे हैं? (केवल लक्ष्य के रूप में उपयोग कर सकते हैं, नहीं स्रोत)" – dsgdfg

उत्तर

0

ऐसा लगता है कि आपको बस उस त्रुटि की जांच करनी होगी और यदि यह दिखाई देता है तो कनेक्शन पुनः स्थापित कर सकता है। निम्न का प्रयास करें:

try: 
    logging.debug("debug log message") 
except IOError, e: 
    if e.errno == 32: 
     logging.config.fileConfig('logging.cfg') 
     logging.debug("debug log message") 
+0

यह शायद समझ में आता है इसे एक फ़ंक्शन डीबग (संदेश) में बदलने के लिए। – MKesper

+1

आपके सभी लॉगिंग कॉल के चारों ओर एक कोशिश/पकड़ डालने से वास्तव में अप्रिय लगता है। जैसे @ एमकेस्पर ने कहा, आप इसे सब कुछ एक समारोह में सेंक कर सकते हैं, लेकिन लॉगिंग करने वाले आपके द्वारा उपयोग की जाने वाली किसी भी पुस्तकालय को इस प्रयास/पकड़ का लाभ नहीं मिलेगा। – matt

1

मैं इस समस्या में भाग गया। मुझे एक कस्टम हैंडलर लिखना पड़ा जो टूटने वाले पाइप अपवादों को संभालता है और सॉकेट को फिर से बनाता है।

class ReconnectingSysLogHandler(logging.handlers.SysLogHandler):     
    """Syslog handler that reconnects if the socket closes      

    If we're writing to syslog with TCP and syslog restarts, the old TCP socket 
    will no longer be writeable and we'll get a socket.error of type 32. When 
    than happens, use the default error handling, but also try to reconnect to 
    the same host/port used before. Also make 1 attempt to re-send the   
    message.                  
    """                   
    def __init__(self, *args, **kwargs):           
     super(ReconnectingSysLogHandler, self).__init__(*args, **kwargs)   
     self._is_retry = False             

    def _reconnect(self):              
     """Make a new socket that is the same as the old one"""     
     # close the existing socket before getting a new one to the same host/port 
     if self.socket:               
      self.socket.close()             

     # cut/pasted from logging.handlers.SysLogHandler       
     if self.unixsocket:              
      self._connect_unixsocket(self.address)        
     else:                 
      self.socket = socket.socket(socket.AF_INET, self.socktype)   
      if self.socktype == socket.SOCK_STREAM:        
       self.socket.connect(self.address)        

    def handleError(self, record):            
     # use the default error handling (writes an error message to stderr)  
     super(ReconnectingSysLogHandler, self).handleError(record)    

     # If we get an error within a retry, just return. We don't want an  
     # infinite, recursive loop telling us something is broken.    
     # This leaves the socket broken.           
     if self._is_retry:              
      return                

     # Set the retry flag and begin deciding if this is a closed socket, and 
     # trying to reconnect.             
     self._is_retry = True             
     try:                  
      __, exception, __ = sys.exc_info()         
      # If the error is a broken pipe exception (32), get a new socket. 
      if isinstance(exception, socket.error) and exception.errno == 32: 
       try:                
        self._reconnect()           
       except:               
        # If reconnecting fails, give up.       
        pass               
       else:               
        # Make an effort to rescue the recod.      
        self.emit(record)           
     finally:                 
      self._is_retry = False 
संबंधित मुद्दे