2011-12-23 14 views
6

मैं एक स्थानीय SMTP server स्थापित किया है और logging.handlers.SMTPHandler इस्तेमाल किया इस कोड का उपयोग एक अपवाद लॉग इन करने के ब्लॉक नहीं:कैसे बनाने के लिए SMTPHandler

import logging 
import logging.handlers 
import time 
gm = logging.handlers.SMTPHandler(("localhost", 25), '[email protected]', ['[email protected]'], 'Hello Exception!',) 
gm.setLevel(logging.ERROR) 
logger.addHandler(gm) 
t0 = time.clock() 
try: 
    1/0 
except: 
    logger.exception('testest') 
print time.clock()-t0 

यह पूरा करने के लिए, इस पूरे समय के लिए अजगर स्क्रिप्ट अवरुद्ध 1sec की तुलना में अधिक ले लिया। कैसे? मैं इसे स्क्रिप्ट को अवरुद्ध कैसे नहीं कर सकता?

उत्तर

13

यहां मैं जिस कार्यान्वयन का उपयोग कर रहा हूं, वह है जिसे मैं this Gmail adapted SMTPHandler पर आधारित करता हूं।
मैंने भाग लिया जो एसएमटीपी भेजता है और इसे एक अलग थ्रेड में रखता है।

import logging.handlers 
import smtplib 
from threading import Thread 

def smtp_at_your_own_leasure(mailhost, port, username, password, fromaddr, toaddrs, msg): 
    smtp = smtplib.SMTP(mailhost, port) 
    if username: 
     smtp.ehlo() # for tls add this line 
     smtp.starttls() # for tls add this line 
     smtp.ehlo() # for tls add this line 
     smtp.login(username, password) 
    smtp.sendmail(fromaddr, toaddrs, msg) 
    smtp.quit() 

class ThreadedTlsSMTPHandler(logging.handlers.SMTPHandler): 
    def emit(self, record): 
     try: 
      import string # for tls add this line 
      try: 
       from email.utils import formatdate 
      except ImportError: 
       formatdate = self.date_time 
      port = self.mailport 
      if not port: 
       port = smtplib.SMTP_PORT 
      msg = self.format(record) 
      msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
          self.fromaddr, 
          string.join(self.toaddrs, ","), 
          self.getSubject(record), 
          formatdate(), msg) 
      thread = Thread(target=smtp_at_your_own_leasure, args=(self.mailhost, port, self.username, self.password, self.fromaddr, self.toaddrs, msg)) 
      thread.start() 
     except (KeyboardInterrupt, SystemExit): 
      raise 
     except: 
      self.handleError(record) 

प्रयोग उदाहरण:

logger = logging.getLogger() 

gm = ThreadedTlsSMTPHandler(("smtp.gmail.com", 587), '[email protected]_company.com', ['[email protected]_company.com'], 'Error found!', ('[email protected]', 'top_secret_gmail_password')) 
gm.setLevel(logging.ERROR) 

logger.addHandler(gm) 

try: 
    1/0 
except: 
    logger.exception('FFFFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUUUU-') 
0

शायद आपको अपना खुद का लॉगिंग हैंडलर लिखना होगा जो पृष्ठभूमि में ईमेल भेजना होगा।

+0

उदा। स्थानीय 'sendmail' प्रोग्राम पर कॉल करना जो शायद आपके एमटीए के साथ आया था और एसएमटीपी का उपयोग किए बिना आपके स्थानीय एसएमटीपी सर्वर को प्रस्तुत करता है। – MattH

5

आप QueueHandler और QueueListener का उपयोग कर सकते हैं। डॉक्स से लिया: QueueListener वर्ग के साथ साथ

, QueueHandler संचालकों एक जो प्रवेश करता है से एक अलग थ्रेड पर अपना काम करते हैं यह बताने के लिए इस्तेमाल किया जा सकता। यह वेब अनुप्रयोगों और अन्य सेवा अनुप्रयोगों में भी महत्वपूर्ण है जहां ग्राहकों को सेवा देने वाले धागे जितनी जल्दी हो सके प्रतिक्रिया दे सकते हैं, जबकि संभावित संभावित धीमी परिचालन (जैसे SMTPHandler के माध्यम से एक ईमेल भेजना) अलग थ्रेड पर किया जाता है।

अलास वे केवल पाइथन 3.2 से आगे उपलब्ध हैं।

+2

+1, और वे * पुराने पायथन संस्करणों के लिए logutils प्रोजेक्ट के माध्यम से उपलब्ध हैं: http://plumberjack.blogspot.com/2010/10/logutils-using-recent-logging-features.html –

0

पाइथन में कोडिंग करते समय ध्यान में रखना एक बात है जीआईएल (ग्लोबल इंटरप्रेटर लॉक)। यह लॉक एक ही समय में एक से अधिक प्रक्रिया होने से रोकता है। पाइथन में 'अवरुद्ध' गतिविधियां हैं जो कई चीजें हैं। वे पूरा होने तक सब कुछ रोक देंगे।

वर्तमान में जीआईएल के आस-पास एकमात्र तरीका यह है कि आप एआईक्स और मैटएच जैसे बाहरी स्रोत के लिए प्रयास कर रहे हैं या मल्टीप्रोसेसिंग मॉड्यूल (http: //docs.python) का उपयोग करके अपने कोड को कार्यान्वित करने के लिए प्रयास कर रहे हैं। संगठन/पुस्तकालय/multiprocessing.html) ताकि एक प्रक्रिया संदेश भेजने के लिए है और बाकी को अन्य प्रक्रिया द्वारा संभाला जा रहा है।

2

मेरे लिए अतुल्यकालिक smtp हैंडलर का सबसे सरल रूप में सिर्फ emit विधि ओवरराइड और एक नया सूत्र में मूल विधि का उपयोग करने के लिए है। जीआईएल इस मामले में कोई समस्या नहीं है क्योंकि एसएमटीपी सर्वर पर आई/ओ कॉल है जो जीआईएल जारी करता है। कोड निम्नानुसार है

class ThreadedSMTPHandler(SMTPHandler): 
    def emit(self, record): 
     thread = Thread(target=SMTPHandler.emit, args=(self, record)) 
     thread.start() 
संबंधित मुद्दे