2016-04-29 8 views
2

電子メールアドレスにエラーレベルのログを送信するフラスコアプリケーションを開発しています。 MAIL_USE_SSL=TrueMAIL_PORT=465で、flask-mailを使用して設定した設定値はpythonロギングのSMTPHandlerとSSLを使用して電子メールを送信するには

mail_handler = SMTPHandler(mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']), 
          fromaddr=app.config['MAIL_FROM_EMAIL'], 
          toaddrs=['[email protected]_address.com'], 
          subject='The server died. That sucks... :(', 
          credentials=(app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])) 

注:私は、一般的なエラーハンドラを設定してみました。

しかし、(テスト中の目的で)エラーを呼び出すと、ソケットタイムアウトエラーが発生します。ポート以外では、ハンドラにSSLを使用するように指示する方法がわかりません。 secure=()パラメータが渡されますが(the SMTPHandler docs参照)、SSLではなくTLSを指定しています。

これを行う手掛かりはありますか?ありがとう!

答えて

5

Ned Deilyのおかげで、smtplib(SMTPHandlerの下にある)が特別な処理を必要としていることが分かりました。また、SMTPHandlerをオーバーロードして(その場合はTLSの問題を修正して)、その方法を示すthis postが見つかりました。

smtplib.SMTPではなく、smtplib.SMTP_SSLsee smtplib docs)を使用することで、システム全体を動作させることができました。これは、と私のアプリケーションファイルに登録されている

from your.application.file import app 

import smtplib 
import logging 
from logging.handlers import RotatingFileHandler, SMTPHandler 


# Provide a class to allow SSL (Not TLS) connection for mail handlers by overloading the emit() method 
class SSLSMTPHandler(SMTPHandler): 
    def emit(self, record): 
     """ 
     Emit a record. 
     """ 
     try: 
      port = self.mailport 
      if not port: 
       port = smtplib.SMTP_PORT 
      smtp = smtplib.SMTP_SSL(self.mailhost, port) 
      msg = self.format(record) 
      if self.username: 
       smtp.login(self.username, self.password) 
      smtp.sendmail(self.fromaddr, self.toaddrs, msg) 
      smtp.quit() 
     except (KeyboardInterrupt, SystemExit): 
      raise 
     except: 
      self.handleError(record) 


# Create file handler for error/warning/info/debug logs 
file_handler = RotatingFileHandler('logs/app.log', maxBytes=1*1024*1024, backupCount=100) 

# Apply format to the log messages 
formatter = logging.Formatter("[%(asctime)s] | %(levelname)s | {%(pathname)s:%(lineno)d} | %(message)s") 
file_handler.setFormatter(formatter) 

# Set the level according to whether we're debugging or not 
if app.debug: 
    file_handler.setLevel(logging.DEBUG) 
else: 
    file_handler.setLevel(logging.WARN) 


# Create equivalent mail handler 
mail_handler = SSLSMTPHandler(mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']), 
          fromaddr=app.config['MAIL_FROM_EMAIL'], 
          toaddrs='[email protected]', 
          subject='Your app died. Sad times...', 
          credentials=(app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])) 

# Set the email format 
mail_handler.setFormatter(logging.Formatter(''' 
Message type:  %(levelname)s 
Location:   %(pathname)s:%(lineno)d 
Module:    %(module)s 
Function:   %(funcName)s 
Time:    %(asctime)s 

Message: 

%(message)s 
''')) 

# Only email errors, not warnings 
mail_handler.setLevel(logging.ERROR) 

:これは私が(ファイルの良い例である必要があり、同様に、電子メール、ハンドラ)ハンドラを設定するために使用utilsの/ logs.pyファイルです。

# Register the handlers against all the loggers we have in play 
# This is done after app configuration and SQLAlchemy initialisation, 
# drop the sqlalchemy if not using - I thought a full example would be helpful. 
import logging 
from .utils.logs import mail_handler, file_handler 
loggers = [app.logger, logging.getLogger('sqlalchemy'), logging.getLogger('werkzeug')] 
for logger in loggers: 
    logger.addHandler(file_handler) 
    # Note - I added a boolean configuration parameter, MAIL_ON_ERROR, 
    # to allow direct control over whether to email on errors. 
    # You may wish to use 'if not app.debug' instead. 
    if app.config['MAIL_ON_ERROR']: 
     logger.addHandler(mail_handler) 

これが誰かを助けることを願っています!

関連する問題