When monitoring a production website (especially with a dozen or so application servers) you don’t want to rely on combining the logs and reviewing them manually for exceptions, you want the servers to notify you when there’s a problem. There are really 3 pieces to doing this properly and they are:
1. Configuring an SMTP appender to email you when an error is logged or using a custom appender to send a message to your monitoring server (e.g. NagiosAppender for Nagios)
2. Implementing a ServletFilter or other interceptor that logs Exceptions that would otherwise go to the top of the application server stack. You can do this directly with most application servers but I prefer using a ServletFilter because you have access to the HttpServletRequest so you can write out additional information such as the referrer, user-agent, remote ip, cookies, requested URL, etc… along with the stack trace.
3. Configuring error pages for 404’s and 500’s so your users never see a stack trace.
In this post we’ll just look at configuring the SMTP appender and then I’ll do a followup post with an example ServletFilter and configuring the error pages in Tomcat.
Configuring log4j to send email when an error is logged (or warning if you prefer) is easy. Just add mail to the log4j.rootCategory in log4j.properties and add the following to log4j.properties:
log4j.appender.Mail.layout.ConversionPattern=%d %-5p %c %x - %m%n
I prefer the non-XML properties version of log4j configuration but if you want the XML syntax for a log4j SMTP appender here it is.
Now when you log an error it will be emailed to you. It’s critical though that you tune the site to only log errors when there’s a real problem and use a group email alias that you can disable until you fix the issue if too many messages are coming in. Otherwise, people will add rules to their email clients to send the messages to a separate folder and just ignore them which defeats the purpose.
The most common mistake I’ve seen when consulting at other companies is that programmers catch unrecoverable exceptions in their application code, log them, and rethrow them resulting in duplicate messages. Or even worse, they catch them and display their own page specific error page instead of using a site wide configurable 500 error page offered by all application servers.
You should generally never have to catch and rethrow an unrecoverable exception in your application code unless you want to add a specific message for the generic 500 page to show! Unrecoverable exceptions SHOULD go to the top of the stack and that’s what the ServletFilter and configurable error pages are for that we’ll talk about in parts 2 and 3.
Related reading: This ONJava article describes configuring java.util.logging and log4j with smtp appenders, Matt Raible’s entry on using Log4j SMTP appenders