PR

404エラーを管理者にメール報告するプログラム

開発コンセプト

以下のような引っ越しプログラムで、引っ越し先を案内した。

親切な「移転しました」を案内するperlスクリプト

さて、引っ越し先でもきちんと移転はできただろうか。報告してくれるプログラムを作ってみた。

(追記)しばらく使ってみた感想。何日か使ってみているわけだけど、これはかなり重宝してます。

  • 多くが過去に作ったページが参照しているCSSファイルへのリンクが間違っていたり、サイトの移転やパスの変更などで発生したエラーだ。エディタにそれらを検出する機能をもったものもあるがあまり勝手の良いものではない。
  • 少なくともエラーが即座に把握できるから、メーラーをタスクリストとして確実に潰していける。すぐに対応できないときは、報告された場所にその名前で代替品を置けばユーザビリティもよい。
  • 発展的な使い方をすれば、パスごとにだれが担当者かを分類して、傾向と対策や、完成度の評価につなげてもよいかもしれない。

スポンサードリンク

報告メール例

This error was reported to the manager./common/spacer.gif
Ref = http://www.***.jp/index.htm
218.XXX.142.XXX
 2009/1/5(Mon) 1:0:25
(C)CASEY.JP, 404report.cgi Ver.0.01

 

This error was reported to the manager./support/mail/index.htm
Ref = http://www.***.jp/hoge/index.htm
202.XXX.100.XXX
 2009/1/4(Sun) 18:28:53
(C)CASEY.JP, 404report.cgi Ver.0.01

プログラム

 #!/usr/local/bin/perl
 #-----------------------------------------------------------------------------
 # 404report.cgi - 404エラーを管理者にメールで報告するプログラム -
 #-----------------------------------------------------------------------------
 # License GPL
 # Copyright 2009 CASEY
 # History
 # - 2009-01-04 Ver.0.01 初版作成
 #------------------------------------------------------------------------------
 # [注意事項]
 #  - このプログラムは起動すると即座に動作、報告する。データの蓄積を行わないので
 #    起動が多ければ膨大な報告が寄せられることがあるので注意すること。
 #    (特にメール送信や負荷に関してサーバー管理者に迷惑をかけないように注意)
 #  - メールに日本語を使うことを想定していない
 #    (日本語を使いたい場合はエンコードしてあげれば行けると思う)
 #  - メールの送信認証には対応していない
 # [.heaccessによる起動]
 #  - 404, 呼び出したファイルが存在しないことの通知
 #  - 500, CGIの呼び出しがエラーになったことの通知(非推奨)
 # [.htaccess記述例]
 #   ErrorDocument 404 /404report.cgi
 #------------------------------------------------------------------------------
 use strict;
 use CGI::Carp qw(fatalsToBrowser);
 use Mail::Sendmail;
 use Encode;
 use utf8;# 設定ここから ----------------------------------------------------------------
 my $to  = '*****hotmail.com';  # 連絡先メールアドレス

 # 以降は変更しない ------------------------------------------------------------
 my $from = 'root@localhost';    # 送信者
 my $ver  = '404report.cgi Ver.0.01';  # プログラム名
 my $subject = $ver;       # 件名
 $|=1;

 # アクセス元が取得できない場合は処理を中断
 #   コメントアウトすればすべてのエラーを通知させることができるが、
 #   ハッキングプログラムなどがわざわざ存在しないものや、
 #   攻撃コードを持ってくることもあるので、注意が必要。
 #   どんなサーバでも最低3000件/Dayくらいの不正アクセスはあるハズ。
 if(!$ENV{'HTTP_REFERER'}){
 print "Content-Type: text/html; charset=UTF-8\n\n";
 print "STOP [CHK_REFERER]";
 exit;
 }

 # 日付処理
 my @youbi = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fry', 'Sat');
 my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
 $year += 1900;
 $mon += 1;
 my $dt = "$year/$mon/$mday($youbi[$wday]) $hour:$min:$sec";

 # メッセージ組み立て
 my $message = "This error was reported to the manager.\n\n";
 $message .= "$ENV{'REQUEST_URI'}\n\n";

 if($ENV{'HTTP_REFERER'}){
 $message .= "Ref = $ENV{'HTTP_REFERER'}\n";
 }else{
 $message .= "Ref = ?\n";
 }

 $message .= "\n";
 $message .= "$ENV{'REMOTE_ADDR'}\n";
 $message .= "$dt\n";
 $message .= "\n(C)CASEY.JP, $ver\n";

 # エンコード
 $subject = encode("MIME-Header-ISO_2022_JP", $subject);
 $message = encode("iso-2022-jp", "$message");

 # メール作成
 my %mail = (
 "Content-Type" => 'text/plain;charset="iso-2022-jp"',
 To             => $to,
 From           => $from,
 Subject        => $subject,
 Message        => $message,
 );

 # メール送信
 sendmail(%mail);

 # 完了画面出力開始 ------------------------------------------------------------
 # STATUS 404, 500 を返してもいいかもしれないけど…(Defaultは当然200)
 $message =~ s/\n/<br>\n/g;
 print "Content-Type: text/html; charset=UTF-8\n\n";
 print <<"END_HTML";
 <h1>ERROR</h1>
 $message
 END_HTML

▲404が表示され、管理者には連絡がある。

▲直接アクセスするとメールは送られず、動作チェックできる

ダウンロード

参考文献

コメント

  1. ゲストユーザ より:

    # 404report.cgi – 404エラーを管理者にメールで報告するプログラム -の使い方を教得てください。
    .htaccessを使用して、カスタマイズしたnot_found.htmlにリダイレクトしています。
    訪問者に対しては、not_found.htmlを表示して、同時に、これが表示された場合には管理者にメールが届くようにしたいと思っています。標題のcgiプログラムは、そのような用途に使用できますか?
    可能なら、404report.cgi のカスタマイズ方法を教えて下さい。
    .htaccessには、カスタマイズしたnot_found.htmlのurlと同時に404report.cgi のurlを記入し、(カスタマイズした)404report.cgiを.htaccessで指定したディレクトリに置くだけで動作するのでしょうか?
    また、利用規約等があるのでしょうか?

  2. ゲストユーザ より:

    追加でお聞きします。このcgiプログラムでカスタマイズする項目は、$to に管理者のメールアドレスを設定するだけで使えるのでしょうか?掲載されているコードをエディタで、このプログラム名で保存すればよいですか?保存はutf-8にすればよいでしょうか?

  3. CASEY より:

    >標題のcgiプログラムは、そのような用途に使用できますか?
    はい。できます。しかし、サーバーや設定によっては期待通りの結果を表示しないことがあります。挑戦してみてください。
    >置くだけで動作するのでしょうか?
    その設置方法で動作ると思います。.htaccessについてはパスの指定方法に注意してください。
    また、cgiの基本的な設置方法についてはパーミッション707などで動作すると思います。
    管理者向けプログラムなのでこの辺は了解している人が利用することを想定しています。
    (=そうでないと単純なプログラムなのでサーバーに迷惑をかけてしまうかもしれません)
    #設置して、ありえないファイル名を指定した時にメールが受信できればとりあえず成功ですね

  4. CASEY より:

    >利用規約
    GPLなので自由に使って下さい
    http://www.gnu.org/licenses/gpl.html(原文)
    以下は日本語訳です
    http://www.opensource.jp/gpl/gpl.ja.html.euc-jp

  5. CASEY より:

    >$to に管理者のメールアドレスを設定するだけ
    はいそうです。送信に認証が必要だとか込み入った設定の必要な環境はできません。
    (=自分のサーバを想定しているのでlocalhostのMTAを使うのでいいかなーという感じです)
    >保存はutf-8にすればよいでしょうか?
    難しいことはしていないのでUTF-8でもS-JISでも動くと思いますが・・・
    うろ覚えなのでダウンロードしたファイルをそのまま使ってください((+_+))
    #エディタで編集する程度ではコードが変更されることはないと思いますので

  6. ゲストユーザ より:

    ご返信、ありがとうございます。
    通知先のメール管理者を2名とするには、
    # 設定ここから —————————————————————-
    my $to  = ‘*******@hotmail.com’;  # 連絡先メールアドレス
    の部分をどのように設定すればよろしいでしょう?
    現在.htaccessは、
    http://www.***.co.jp/の直下(ルート)にあり、
    記述は、次のような直接的な表現で動作している状況です。not_found.htmlはルートより一つ下のerrorディレクトリとしています。
    ErrorDocument 403 http://www.***.co.jp/error/not_found.html
    ErrorDocument 404 http://www.***.co.jp/error/not_found.html
    ErrorDocument 500 http://www.***.co.jp/error/not_found.html
    これを、下記のようにすればよいですか?(404の場合だけ通知されるとして)
    ErrorDocument 403 http://www.***.co.jp/error/not_found.html
    ErrorDocument 404 http://www.***.co.jp/error/not_found.html
    ErrorDocument 404 http://www.***.co.jp/404report.cgi
    ErrorDocument 500 http://www.***.co.jp/error/not_found.html   &nbsp;
     
    また、設定項目は以上で全てだと理解しましたが、不足等ありましたら、ご指摘ください。大変便利なプログラムなので、期待しています。以前、雑誌「WEB CREATOR」の2008.8月号で、カスタマイズしたnot_found.htmlの冒頭にphpスクリプトを追加してnot_found.phpとしてアップロードする方法が紹介されていたのですが、実際にnot foundを発生させなくても、やたらとメールが来てしまい、デバッグできずに悩んでいたところです。今回は、not_found.htmlは現行のまま、変更せずに使えるし、cgiを一つアップロードするだけなので、シンプルな作業になると感じています。
    以上、よろしくお願いします。

  7. CASEY より:

    >通知先のメール管理者を2名とするには、
    メールサーバで転送設定を行えば行けます
    >htaccessは、
    新しいファイルに更新しておきましたのでダウンロードしてください。
    .htaccessのサンプルも入れておきました。
    >雑誌「WEB CREATOR」2008.8月号で、phpスクリプトを追加
    そっちのほうが良いかも知れませんね・・・。
    私は基本がperlなので思いつきませんでしたが。
    フックも実現方法もたくさんありますね。
    私も以前どこかでこのようなプログラムを見つけて便利だと思っていたのですが、見つからなかったので作りました。
    ただ、骨格部分しかないものなので、これ以降は皆様で発展させてください。
    >やたらとメールが来てしまい
    検索エンジンやブラウザがファビコンやrobots.txtなどを探しに来ると反応しますね。
    アクセス数の多いサイトだとこのプログラムだと対応できないかも知れませんね。

  8. ゲストユーザ より:

    ありがとうございます。転送設定という基本的なものがありましたね^^
    さて、.htaccessを添付していただき、ありがとうございます。私の設定の
    方法でもいいんですよ?(やってみればいいか^^;;)心配してたのは、
    404の時の処理を2とおり(つまり、一つはnot_found.htmlにリダイレクト、もう一つは404report.cgi、のように二つの設定が有効になるかどうか、という点でした。とにかくやてみないことにはわかりませんよね?)
    あと、このcgiは、404発生で起動し、管理者へメール送信した時点で終了しますか?
    以上お聞きして、今夜9時過ぎに実施したいと考えています。よろしくお願いします。
     

  9. CASEY より:

    >つまり、一つはnot_found.htmlにリダイレクト、もう一つは404report.cgi、のように二つの設定が有効になるかどうか、という点でした。とにかくやてみないことにはわかりませんよね?
    これはどうでしょうねー?cgiではなくApacheの範囲になってくるような気がします。。。
    2件処理できたらラクですね。
    >あと、このcgiは、404発生で起動し、管理者へメール送信した時点で終了しますか?

    httpdにリクエストが来る
    httpdがファイルを探す
    ファイルが見つからない→404の発生
    .htaccessを参照して404のときどうするか調べる
    404report.cgiが設定されている
    404report.cgiに処理を渡して、httpdは処理終了

    上記のような動作じゃないかなと思いますがApacheのエキスパートではないのでその辺はそちらのMLなどに投げてみてください。
    とりあえず設置手順としては次のようになるかと思います

    このサイトからダウンロードする
    ファイルを解凍する
    エディタ開き、メールアドレスを設定、保存する
    FTPで転送する
    404report.cgiに実行権限を設定する(700/707)
    設置したアドレスにブラウザからアクセスする
    例:http://hoge.com/404report.cgi
    起動メッセージが出たらOK、出なかったらperlパスやパーミッションの確認などする
    .htaccessを有効にする
    存在しないファイルを呼び出す
    例:http://hoge.com/nothing.html
    メールが届けばOK、届かないときはSSHやログで確認する

     

  10. ゲストユーザ より:

    ザンネン・・・

    このサイトからダウンロードする
    ファイルを解凍する
    エディタ開き、メールアドレスを設定、保存する
    FTPで転送する
    404report.cgiに実行権限を設定する(700/707)
    設置したアドレスにブラウザからアクセスする
    例:http://hoge.com/404report.cgi
    起動メッセージが出たらOK、出なかったらperlパスやパーミッションの確認などする

    起動メッセージが出ません。以下のメッセージでした。
    Software error:

    Can't locate Mail/Sendmail.pm in @INC (@INC contains:
    /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi
    /usr/lib64/perl5/site_perl/5.8.7/x86_64-linux-thread-multi
    /usr/lib64/perl5/site_perl/5.8.6/x86_64-linux-thread-multi
    /usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7
    /usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5
    /usr/lib/perl5/site_perl
    /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi
    /usr/lib64/perl5/vendor_perl/5.8.7/x86_64-linux-thread-multi
    /usr/lib64/perl5/vendor_perl/5.8.6/x86_64-linux-thread-multi
    /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl/5.8.7
    /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl/5.8.5
    /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi
    /usr/lib/perl5/5.8.8 .)
    at /virtual/124.***.***.***/home/404report.cgi line 25.
    BEGIN failed--compilation aborted at /virtual/124.***.***.***/home/404report.cgi line 25.
    

    For help, please send mail to the webmaster (admin@***.co.jp), giving this error message and the time and date of the error.
    Line25は、「use Mail::Sendmail;」となっているので、このサーバーにはMail::Sendmailというパール・モジュールがない、または使えない、ということでしょうか?
    長すぎてエラーメッセージが読めません。
    惜しいなぁ。cgiのパーミッションは、サイト内のたのcgiで実績のある707,740などでやってみました。
    以上の情報から、何か判ればアドバイスください。よろしくお願いいたします。
     

  11. ゲストユーザ より:

    当方のレンタルサーバーのWEBサイトには、http://web.arena.ne.jp/suitex/support/manual/hp/script.html#module
    というページがあり、その中に、
    7.sendmailの使用
    CGIでメールを送信する処理を行う場合は、サーバーに用意されているsendmailをご利用頂く事が出来ます。
    sendmailが置かれているサーバー上のパスは、 /usr/lib/sendmail もしくは /usr/sbin/sendmail です。 CGIスクリプト内で記述するコマンドの書式は、以下の様になります。
    /usr/lib/sendmail -t -f(発信元アドレス)
    (発信元アドレス)にはメールの発信元として使用するメールアドレスを入力して下さい。 通常はお客さまご自身のメールアドレスを設定します。 例えば、お客さまのメールアドレスが[email protected]の場合は
    /usr/lib/sendmail -t [email protected]
    と記述して下さい。
    という説明がありますが、ヒントになりませんでしょうか?

  12. CASEY より:

    Can’t locate Mail/Sendmail.pm in @INC
    これを解決してあげれば問題ないですね。
    ◆参考サイト
    Movable Typeメール送信時のエラー – パソコンのトラブルとノウハウ・オンラインコンサルタントWiki :
    http://onlineconsultant.jp/pukiwiki/index.php?Movable%20Type%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%81%E4%BF%A1%E6%99%82%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC

  13. ゲストユーザ より:

    参考情報をありがとうございます。
    Sendmail.pm
    というファイルを準備いたしましたが、このファイルをFTPすべきディレクトリはどこになりましょうか?今回の場合MovableTypeとは直接関係がないのです。

  14. ゲストユーザ より:

    当方のレンタルサーバのerlパスが
    /usr/local/bin/perl
    ということなので、ホスティング先に頼んで
    Sendmail.pm
    を上記パスの位置においてもらう、ということですね?

  15. CASEY より:

    それは対応してくれないんじゃないかなと思います。。。

  16. CASEY より:

    以下のサイトなどが参考になりますよ。
    sendmail 8.12 の導入(sendmailのインストール) :
    http://www.stackasterisk.jp/tech/systemConstruction/sendmail01_02.jsp

  17. ゲストユーザ より:

    sendmailのインストールは、自分のドメインにインストールして使う、というより、WEBサーバーにインストールするということになりましょうか?

  18. CASEY より:

    ドメインにインストールできないのでWEBサーバにインストールします。

  19. ゲストユーザ より:

    3月末に一度お尋ねさせていただいた者です。あの時は、sendmailのことが分からず、404report.cgiを動作できませんでした。最近、アンケートフォームの送信を改良している過程で、sendmailを使用していたので、同様にできる筈だと解りました。雛型の404report.cgiに対して、 my $to = ‘自分のアドレス’; の直後に $sendmail =’/usr/sbin/sendmail’; を追加し、動作を確認しましたが、 Software error: Can’t locate Mail/Sendmail.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.7/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.6/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7 /usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.7/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.6/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl/5.8.7 /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at /****/home/404report.cgi line 25. BEGIN failed–compilation aborted at /*****/home/404report.cgi line 25. For help, please send mail to the webmaster (admin@*****), giving this error message and the time and date of the error. と、以前と同じメッセージが出ました。何がいけないのでしょうか?

  20. ゲストユーザ より:

    続きです。 my $sendmail = ‘/usr/sbin/sendmail’; の「my」がなかったためのエラーでした。(use strictを宣言していたんでしたね・・・)さて、無事起動はしたのですが、フツーに言う404エラーではうまく動作しません。 http://www.home.co.jp/index.html のところを、 http://www.home.co.jp/indox.html とアクセスすると、当然ブラウザには404と表示されますが、メールは送られてきません。
    ただ、img要素に記述されたsrc属性や、link要素に記述されたhref属性のurlが実在しない場合には確実にメールが来るようです。これはこれで有り難いのですが、いわゆるリンク外れを知らせてくれるようにするにはどうすればよいでしょうか?

  21. ゲストユーザ より:

    続きを報告します。所期の動作をしていることが確認できました。お騒がせしてスミマセン。さて、そこで次の点を教えていただければ、更にありがたいです。.htaccessの書き方です。以前もお聞きしたのですが、 ErrorDocument 404 /404report.cgi と設定すれば、もちろんOKです。私は、404report.cgi を起動すると同時に、ブラウザにはカスタマイザしたnot found.htmlを表示させたいと思っています。つまり、 ErrorDocument 404 http://www.****/not_found.html も同時に設定したいのですが、この追加1行の設定がどうしても有効になりません。 404report.cgi には、sendmailを起動すると同時に、sendmailの内容と同じものをブラウザに表示していますが、sendmailを起動だけにすれば、not_found.htmlが起動するのではないでしょうか?もし、そうするなら、404report.cgi をどのように変更すればよいでしょうか?

  22. ゲストユーザ より:

    やはり.htaccessでは、 ErrorDocument 404 /404report.cgi を書くと、リダイレクトはこちらが優先されてしまう(同時にnot_found.htmlを起動できない)のかもしれないですね。 404report.cgi の末尾あたりにsendmailの内容を表示するヒアドキュメントがあるので、ここにjavascriptを記述して、not_found.htmlにジャンプさせることで当面は対応できそうです。 いろいろお騒がせしました。役立つプログラムを公開してくださって、ありがとうございました!