java

 

jsp内のエラーをロガーで拾ってアラートメールを送信する

jsp内で起きるエラーは通常catalina.outに出力されます。それだとlog4j・logbackのSMTPアペンダでアラートメールを送信できません。el式の記述ミスやjsp内でのヌルポをロガーで拾ってアラートメールを送信しましょう!

新サイト、tree-mapsを公開しました!!

tree-maps: 地図のWEB TOOLの事ならtree-mapsにお任せ!

地図に関するWEB TOOL専門サイトです!!

大画面で大量の緯度経度を一気にプロット、ジオコーディング、DMS<->DEGの相互変換等ができます!

◯ 広告

サーブレットコンテナにtomcatを使っている場合のお話です。

jsp内で起きるエラーは通常catalina.outに出力されてしまいます。

すると、ロガーのSMTPアペンダでerrorレベルのログをメール送信、等はできません。

このままでは非常に不便なので、是非対応させたいと思います。

最終目標はjspで発生したエラーをlogbackのSMTPアペンダでアラートメールを送信する事です。

ロガー以外はjspの標準機能でカバーできます。

tilesをテンプレートエンジンとして使用しています。

view/
├── common
│   ├── common.jsp
│   ├── footer.jsp
│   ├── header.jsp
│   ├── layout.jsp
│   └── menu.jsp
├── error
│   └── 500.jsp
├── index.jsp
└── layout
    └── main_layout.jsp

まず最初にjsp内で500を検知した際に500.jspに遷移するよう設定します。

web.xmlに設定が必要です。project/src/main/webapp/WEB-INF/web.xmlの末尾に以下を追加します。

<error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/view/error/500.jsp</location>
</error-page>

これで500のエラーコードを検知した際に、500.jspに遷移するようになります。

500.jspにisErrorPage属性を追加します。

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%>
<tiles:insert template="/WEB-INF/view/layout/main_layout.jsp">
<tiles:put name="content">
<p>システム障害が発生しました。</p>
</tiles:put>
</tiles:insert>

isErrorPageを有効にしたjsp内ではexceptionという暗黙オブジェクトが利用可能になるのです。

つまりjsp内で発生したエラーをexceptionから拾えるのです。

では500.jspを以下のようにしたらどうでしょうか?

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%>
<%
    org.slf4j.LoggerFactory.getLogger("jspLogger").error(exception.getMessage(), exception);
%>
<tiles:insert template="/WEB-INF/view/layout/main_layout.jsp">
<tiles:put name="content">
<p>システム障害が発生しました。</p>
</tiles:put>
</tiles:insert>

exceptionが有るという事はロガーに渡せばアラートメールが送信できるのです!

この例ではslf4jとlogbackのコードですが、commons-loggingとlog4jでも問題ありません。

SMTPアペンダは javax.mail に依存しているので追加します。

mavenの場合は以下をpom.xmlに追加しましょう。

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.7</version>
</dependency>

errorレベル以上のログを検知した際に、SMTPアペンダでアラートメールを送信する設定です。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <property resource="logback.properties"/>

    <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <smtpHost>${smtpHost}</smtpHost>
        <smtpPort>${smtpPort}</smtpPort>
        <from>${from}</from>
        <to>${to}</to>
        <subject>${HOSTNAME} - %m</subject>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>[%-5level][%d{yyyy-MM-dd HH:mm:ss.SSS}] %class - %msg%n</Pattern>
        </layout>
        <!-- webアプリの場合はtrue、バッチの場合はfalseを設定します -->
        <asynchronousSending>false</asynchronousSending>
    </appender>

    <root>
        <level value="INFO" />
        <appender-ref ref="EMAIL" />
    </root>
</configuration>

${xxx}の部分はlogback.propertiesでキーバリュー形式で設定しています。

${HOSTNAME}は暗黙変数で、/etc/hostsに設定したホスト名が設定されています。

例えばindex.jspを以下のように記述します。

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<tiles:insert template="/WEB-INF/view/layout/main_layout.jsp">
<tiles:put name="content">
<h1>ハローワールド</h1>
${f:xxx(xxxx)}
</tiles:put>
</tiles:insert>

勿論f:xxxなどという関数は存在しないので、jsp内でエラーが発生します。

この画面にアクセスすると以下のようになります。

jspのエラーをロガーに渡す

この500.jspには前述のようにerrorレベルのロガーが仕込んであります。

そしてSMTPアペンダはerrorレベル以上のイベントをキャッチしメールを送信します。

ではメールが送信されたか確認しましょう。

jspのエラーをgmailで確認

gmailにメール来ましたよ!!!文字化けもしてません!!!

これでjspで発生したエラーも見逃しません!!

macでローカル環境のみでメールを送信したい場合、以下のようにpostfixを起動しましょう。

localhost:WEB-INF tree$ sudo /usr/sbin/postfix start
Password:
postfix/postfix-script: starting the Postfix mail system
◯ 広告