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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <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
.
I have been a long time user (and customer) of IntelliJ IDEA. I think I have started using it around 2005 or 2006, version 5.0 at the time. I was an Eclipse user back then. A few of my colleagues recommended it to me, and at first I was not convinced, but after trying it out I was impressed.
Now in 2014, IntelliJ IDEA is still my IDE of choice. The intent of this post is not to start an IDE war, but to focus on a few of IDEA features that sometimes other IDEA users are not aware of.
Darcula Theme
The Darcula Theme changes your user interface to a dark look and feel. Well, maybe this is nothing new for you, but I would like to point two major advantages. First, it causes much less stress to your eyes. Give it a try! After a few hours using the dark look if you switch to the default one again you’re probably going to feel your eyes burning for a few minutes. Second, if you’re a mobility addict and you’re always running on battery, the dark look can also help your battery to last longer.

Postfix completion
Postfix completion is the feature that I always wanted and I didn’t even know it. Postfix completion allows you to change already typed expressions. How many times all of us have cursed for having to return back to add a missing cast? Or because we actually wanted to System.out the expression? Well, Postfix completion fixes that.
For instance for the System.out, you type the expression:
someVar
You can now type:
someVar.sout
And the expression is transformed to:
System.out.println(someVar);
Check this awesome post in IntelliJ Blog for additional information about Postfix completion.
Frameworks and Technologies Support
In the Java world, you have a lot of frameworks and technologies available. Most likely you will come across to many of them in your developer work. Sometimes, it’s a nightmare to deal with the additional layer and the required configuration for everything to work correctly.
Look at Maven for instance, it’s a pain to find which dependency to import when you need a class. IDEA Maven support, allows you to search for the class in your local repository and add the correct dependency to your pom.xml file.
Just type the name of the class, press Alt + Enter and Add Maven Dependency:

Pick the library you need. It’s added automatically to your pom.xml.

You have support for Java EE, Spring, GWT, Maven and many others. Check here for a full list.
Inject Language
With Inject Language, it’s possible to have syntax, error highlighting and code completion for a large number of languages into String literals. I use GWT a lot, and this allows me to be able to write safe HTML into the String HTML parameters of the API, like this:

Other examples include, SQL, CSS, Javascript, Groovy, Scala and many others. Try it out by yourself by pressing Alt + Enter on a String statement and then Inject Language.
Presentation Mode
Did you ever had the need to make a presentation about code using your IDE and the audience is not able to see it properly due to font size? And then you have to interrupt your presentation to adjust it. Sometimes you don’t even remember where to adjust it. Wouldn’t be easier to just have a dedicate presentation mode? Just go to View menu and then Enter Presentation Mode option.
Conclusion
I do believe that choosing an IDE is a matter of personal preference and you should stick with the one you feel more productive for the task that you have to complete. I still use Eclipse when I have to deal with BPM stuff.
Some of these features also exist on the other IDE’s, but I have the impression by chatting with other developers that they don’t know about their existence. Explore your development environment and I’m pretty sure you will learn something new. I’m always learning new stuff in IntelliJ IDEA.
Missing a feature you love? Feel free to post it in the comments section!
I’m now working as a Freelancer for more than a year and I think it’s time to write about it again. I previously wrote about Five Ways to Not Suck at Being a Java Freelancer and I even delivered a quick session at Geecon. There is no video yet (should be released soon), but the slides are available.
Anyway, I do get asked a few questions that are not covered in the article or the presentation, so I had the idea to write this post and share my vision as a FAQ. The questions are in no particular order and they reflect my personal experience and should not be treated as an absolute truth.
How do you get clients?
There is no single source to look at. My first client was my previous company. It may look weird, but it was good for everyone. They already knew me and they didn’t have to spend resources looking for other professionals. For me, I was already identified with the company work methods and knew everyone. It was a great way to start.
My next client approached me on LinkedIn. It’s truth that you get a lot of requests and most of them are not interesting, but you only need one to make it worth it. Create a LinkedIn profile and keep it updated and clean. You might get the opportunity that you are looking for.
You can also obtain clients with business cards and colleagues / friends references. Do not underestimate their power. You never know when you are going to bump into someone that has a problem that you can fix (or your colleagues / friends). I was also able to get a few this way.
I do stay away from the platforms that sell you freelance jobs. There is too much competition there, and I prefer to create long time relationships with my clients.
How do I charge my clients?
You should take into account a few factors: the client location, the market in which he operates and your experience with the task in hands.
If you only have 1 year experience with Android, you cannot charge as much as if you have 8 years experience with Java EE. You can usually charge higher for clients operating in the finance sector, but be aware of location. Portugal for instance has very low rates, but in Ireland these are much higher.
It’s fine to charge an hourly or daily rate with different values. Just remember that you and your client must both be comfortable with the rate or you end up risking the business relationship since one of you could become unhappy.
How do you plan the work?
Clients just tell me what they need and I estimate how much time do I need to complete the task. They might not agree with my estimation so you should negotiate with them. Have a look into an post I wrote about estimations: Why it’s challenging to make estimations about code.
What if you exceed you estimation?
First of all, you need to understand why did that happen. Were you very optimistic in the estimation? Did the client provide you with all the information you needed? Or maybe the client added a few extras after the original estimation?
Sometimes you are going to make mistakes and you need to work a few extra hours to finish the work without any extra compensation. No matter what, always be transparent with your client and share everything with him. He will surely understand and help you out.
In other occasions, this will be the client responsibility. You need to negotiate with him, and share with him the possible delays and adjust your estimation and/or price.
How do you deal with multiple clients?
Having multiple clients does not mean that you are working for all at the same time. Important thing here is planning. If they ask you something and you are already occupied, there is no harm in declining. It’s better than accepting multiple tasks and not being able to deliver them properly.
You can always try to postpone the tasks by negotiating with your client. It depends a lot on your client schedule, but if you can pull it off it helps you keep your pipeline for the future.
Do you work in a team?
Yes, most of my work is with a team. In today’s world is hard to do something alone, so it’s only natural to work with other people. I don’t feel that I’m treated differently just because my contractual situation is different. I’m just another member of the team doing my job.
Where do you work?
I work from home most of the time, but I usually go to the client facilities from time to time. For me is important to be able to work remotely due to some personal issues. Clients may not allow you to do that, but you can always propose to work for a few months in their office. When everyone feels comfortable you can switch to remote and return from time to time.
How do you communicate with your clients?
I usually use Skype, Mail and Phone. In these days, there is no reason for not being in constant contact.
How do you deal with timezones?
Since I manage my own schedule, I can always find a suitable time to communicate with my clients, no matter the timezone. Of course it might require you to be available very early or very late.
Do you have a life?
I do! I usually work a regular work week of 40 hours. Sometimes I can work a bit more. The important thing here is to plan your schedule very well, so you can have time for everything.
Missing a question? Feel free to ask it in the comments sections and I’ll be glad to answer it!
I need to start this post by stating that I’ve only started to work seriously with Git within the last year. Unfortunately, a lot of the projects that I work on are still using SVN or CVS, but I’m now finally starting in a few that use Git.
During the last few years, I’ve done a lot of software releases using Maven Release Plugin. I still remember that I’ve took a full week just to setup the plugin in one of my projects. It worked well most of the times, but if something went wrong you could spend the next few hours fixing the problem. Oh boy, what a nightmare!
Recently, I wanted to do the same operation with a Git project and I came across with the Maven JGit-Flow Plugin and I have to tell you that this is fantastic! Very easy to setup and worked flawlessly on the first try!
This plugin is based on the development model described in the post A successful Git branching model by Vincent Driessen. Take your time to read it, since it’s very interesting.
I’m going to show you how to perform a release using this plugin. I’ll use the project from my latest post about Spring Batch as Wildfly Module.
Setup
Setup is very easy, just add the following to your pom.xml
:
| <plugin> <groupId>external.atlassian.jgitflow</groupId> <artifactId>jgitflow-maven-plugin</artifactId> <version>1.0-m3</version> <configuration> <noDeploy>true</noDeploy> </configuration> </plugin> |
I’ve just added the noDeploy
configuration, because I’m not releasing to a Maven repository. That’s it!
Release
Let’s look at my project branches and version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | radcortez:wildfly-spring-batch radcortez$ git branch -avv * master 0b2364b [origin/master] Added documentation. remotes/origin/master 0b2364b Added documentation. radcortez:wildfly-spring-batch radcortez$ mvn help:evaluate -Dexpression=project.version [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building wildfly-spring-batch 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-help-plugin:2.2:evaluate (default-cli) @ wildfly-spring-batch --- [INFO] No artifact parameter specified, using 'com.cortez.wildfly.batch:wildfly-spring-batch:war:1.0-SNAPSHOT' as project. [INFO] 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ |
Now, just run mvn jgitflow:release-start
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | radcortez:wildfly-spring-batch radcortez$ mvn jgitflow:release-start [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building wildfly-spring-batch 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- jgitflow-maven-plugin:1.0-m3:release-start (default-cli) @ wildfly-spring-batch --- [INFO] ensuring origin exists... [INFO] (develop) Checking for SNAPSHOT version in projects... [INFO] (develop) Checking dependencies and plugins for snapshots ... What is the release version for "wildfly-spring-batch"? (com.cortez.wildfly.batch:wildfly-spring-batch) [1.0]: [INFO] ensuring origin exists... [INFO] (release/1.0) adding snapshot to pom versions... [INFO] (release/1.0) updating poms for all projects... [INFO] turn on debug logging with -X to see exact changes [INFO] (release/1.0) updating pom for wildfly-spring-batch... What is the development version for "wildfly-spring-batch"? (com.cortez.wildfly.batch:wildfly-spring-batch) [1.1-SNAPSHOT]: [INFO] (develop) updating poms with next development version... [INFO] (develop) updating poms for all projects... [INFO] turn on debug logging with -X to see exact changes [INFO] (develop) updating pom for wildfly-spring-batch... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ |
You get an interactive menu to pick the version numbers you want to release, the same way as Maven Release Plugin. I’m developing on the master
branch, but during this process a release
branch is created with the release versions and development
branch with the new development versions.
| radcortez:wildfly-spring-batch radcortez$ git branch -avv develop 728856a [origin/develop] updating poms for 1.1-SNAPSHOT development master 0b2364b [origin/master] Added documentation. * release/1.0 9f88a42 updating poms for branch '1.0' with snapshot versions remotes/origin/master 0b2364b Added documentation. |
Now the cool thing about this, is that everything is still in your local environment! If you are not happy with the changes, you can get rid of the branches and start over. No build was performed at this point.
If we want to release, just run mvn jgitflow:release-finish
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | radcortez:wildfly-spring-batch radcortez$ mvn jgitflow:release-finish [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building wildfly-spring-batch 1.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- jgitflow-maven-plugin:1.0-m3:release-finish (default-cli) @ wildfly-spring-batch --- [INFO] ensuring origin exists... [INFO] running jgitflow release finish... [INFO] ensuring origin exists... [INFO] (release/1.0) Updating poms for RELEASE [INFO] (release/1.0) removing snapshot from pom versions... [INFO] (release/1.0) updating poms for all projects... [INFO] turn on debug logging with -X to see exact changes [INFO] (release/1.0) updating pom for wildfly-spring-batch... [INFO] (release/1.0) Checking for RELEASE version in projects... [INFO] (release/1.0) Checking dependencies and plugins for snapshots ... [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building wildfly-spring-batch 1.0 |
In this step, the release
branch is going to get merged as described in A successful Git branching model and create the tag. Remember, nothing has been pushed yet, so you can always revert the process.
Let’s have a look into the branches and tags now:
| radcortez:wildfly-spring-batch radcortez$ git branch -avv * develop a8e762b [origin/develop] Updating develop poms back to pre merge state master b6fbda0 [origin/master: ahead 3] Merge branch 'release/1.0' remotes/origin/master 0b2364b Added documentation. radcortez:wildfly-spring-batch radcortez$ git tag 1.0 |
Now you’re a push away to complete your release and ready to keep developing in your new updated development
branch. How easy was that?
Conclusion
Looking into some differences between the original release plugin and jgitflow:
- You don’t have to worry about stage commits. Everything is local until you push.
- No more problems with other people changing pom.xml during the process.
- Your project is only built once, saving release time.
- Very easy to setup. Everything is picked from your Git configuration.
When I was investigating / writing, I’ve found this very interesting post, about an alternative way to perform the release. It’s worth reading: http://axelfontaine.com/blog/final-nail.html by Axel Fontaine