Moodleからユーザ宛のメール送信が時折失敗していることに気付きました.
mdl_logを
- module = library
- action = mailer
- info = ERROR:%
で検索して見て下さい.もし何もマッチしないならば問題無いのでしょう.
当方では,どうやらMoodleサイト(Winddows/Apache)と学内のsmtpサーバとの間のconnectionが正常に確立されていない状態でメール送信を行なおうとしてエラーになっているようです.
エラーのログが記録されているということは,Moodle側で送信が正常に行なえなかったことを認識しているということで,lib/moodlelib.phpのfunction email_to_user()関数の最後のところで,
add_to_log(SITEID, 'library', 'mailer', $FULLME, 'ERROR: '. $mail->ErrorInfo);
としています.
メール送信に失敗しないサイトが大半だと思いますが,万が一,メール送信に失敗した(smtpなどのサーバが一時的にダウン)場合,そのメールを再送しろとは言いませんし,発信元のユーザに送信失敗を通知するメールを送れとは言いません.なにせ送信に失敗したのですから^^;
でも,できればmessage機能などで,次のログイン時に「何月何日に誰さんに送ったメールは正常に送信できませんでした」と通知できないものでしょうか.
当方では要約メール等を含めて13日間で342件のメール送信があり,そのうちの3件のみですので数は多くありません.
どうやらfsockopen()関数でsmtpサーバに接続した際にfalseが返らずきちんとリソースが返されている.しかしレスポンス("220 smtp.**.**.***.**.ac.jp ESMTP Postfix;")が戻ってきていない場合にエラーになっています.Windows版PHPにはタイムアウトの設定が無効であるという制限もありますし,PHPマニュアルのfsockopen()の説明にも,
警告
UDPソケットは、リモートホストとの接続が確立されていない場合でも、 エラーを発生せずにオープンされたように見えることが時々あります。 このエラーは、そのソケットでデータを読み書きした際にのみ明らかになります。 この原因は、UDPが"コネクションレス"のプロトコルであり、 実際にデータを送受信する必要が生じるまで、 オペレーションシステムがソケット用のリンクを確立しようとしないためです。
とあります.PHPmailerのfunction SmtpCoonect()もRetryを行なうようなコメントはありますが,実際には複数のサーバが指定されている場合は次のサーバをトライするというものであって,同一のサーバにリトライしている訳ではありません.いえ,そもそもfunction Connect()もfsockopen()がfalseでないならば,レスポンスが空でも接続OKと判断していますので,この点から見直さないといけません.
-
fsockopen()によるコネクションの確立に失敗を厳密にチェックする(レスポンスをチェック)
-
connectに失敗したら,せめてもう一度だけトライする
そして,
-
メール送信に失敗したら管理者とメール送信者(cron等からの自動送信メールは除く)に警告する
といった対応が必要ではないでしょうか.特にメール送信失敗の警告は重要だと思うのですが,如何でしょう.私の勘違いで,既にその機能が存在する場合は教えて頂けると助かります.