Enterprise Java

Monitoring and Filtering Application Log to Mail with log4j

In today’s post I’m going to show you how to filter log statements into a warning email. This came out of a necessity to monitor a few critical points of one application I was working on. There are tools that you can use to perform application monitoring. I’m not going into details about those tools, but sometimes it’s just easier to have the application send a warning email.

I mostly use log4j for my logging requirements. Unfortunately, since there are so many logging frameworks in the Java ecosystem this post only covers a piece of it. I might do something for the others in the future, but I would like to reinforce a old post of António Gonçalves about standardize a logging API: I need you for Logging API Spec Lead !. The sample covered here is for log4j, but the github project also contains a log4j2 sample.

Use Case

To give a little more detail, I want to be informed when the application generates erros, but also ignore erros that are already handled by the application itself. For a more concrete example, I had a case where a database insert could generate a constraint violation exception, but this error was handled specifically by the application. Even so, the JDBC driver logs the exception. For this case, I was not interested in getting a notification.

Setting up SMTPAppender

Anyway, looking into log4j, you can create an appender that sends all your log to the email, just check SMTPAppender. It looks like this:

log4j-SMTPAppender

<appender name="SMTP" class="org.apache.log4j.net.SMTPAppender">
    <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>

    <param name="Threshold" value="ERROR"/>
    <param name="To" value="someone@somemail.com"/>
    <param name="From" value="someonelse@somemail.com"/>
    <param name="Subject" value="Log Errors"/>
    <param name="SMTPHost" value="smtp.somemail.com"/>
    <param name="SMTPUsername" value="username"/>
    <param name="SMTPPassword" value="password"/>
    <param name="BufferSize" value="1"/>
    <param name="SMTPDebug" value="true"/>

    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}:%L] %m%n"/>
    </layout>
</appender>

Filtering

Our filtering needs are not available in the standard log4j lib. You need to use the log4j-extras which provide you with ExpressionFilter that supports filtering of complex expressions. We are also using StringMatchFilter from the regular log4j lib.

Now, we can add a triggeringPolicy to the SMTPAppender:

log4j-triggeringPolicy

<triggeringPolicy class="org.apache.log4j.rolling.FilterBasedTriggeringPolicy">
    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="ERROR01"/>
        <param name="AcceptOnMatch" value="false"/>
    </filter>

    <filter class="org.apache.log4j.filter.ExpressionFilter">
        <param name="expression"
               value="CLASS LIKE .*Log4jExpressionFilter.*"/>
        <param name="acceptOnMatch" value="false"/>
    </filter>

    <filter class="org.apache.log4j.filter.LevelRangeFilter">
        <param name="levelMin" value="ERROR"/>
        <param name="levelMax" value="FATAL"/>
    </filter>
</triggeringPolicy>

This configuration will filter the log to email only the ERROR and FATAL thresholds which are NOT logged in classes with Log4jExpressionFilter in it’s name and DON’T have ERROR01 in the log message.

Have a look into LoggingEventFieldResolver to see which others expressions you can use with ExpressionFilter. You can use EXCEPTION, METHOD and a few others which are very useful.

Testing

Testing a SMTPAppender is not easy if you rely on real servers. Fortunately, you can use mock-javamail and you don’t even have to worry about polluting a SMTP server. This is also included in the github project.

Resources

You can clone a full working copy from my github repository for log4j and log4j2.

Log4j Mail Filter

Since I may modify the code in the future, you can download the original source of this post from the release 1.0. In alternative, clone the repo, and checkout the tag from release 1.0 with the following command: git checkout 1.0.

Roberto Cortez

My name is Roberto Cortez and I was born in Venezuela, but I have spent most of my life in Coimbra – Portugal, where I currently live. I am a professional Java Developer working in the software development industry, with more than 8 years of experience in business areas like Finance, Insurance and Government. I work with many Java based technologies like JavaEE, Spring, Hibernate, GWT, JBoss AS and Maven just to name a few, always relying on my favorite IDE: IntelliJ IDEA.Most recently, I became a Freelancer / Independent Contractor. My new position is making me travel around the world (an old dream) to customers, but also to attend Java conferences. The direct contact with the Java community made me want to become an active member in the community itself. For that reason, I have created the Coimbra Java User Group, started to contribute to Open Source on Github and launched my own blog (www.radcortez.com), so I can share some of the knowledge that I gained over the years.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button