I am pretty new to AspectJ and AOP in general. I do know that AspectJ has many Annotations (After, AfterReturning, etc) to execute code before a method is called, after it is called, after it returns, when an exception is thrown, etc.
I would like to use it for logging, a pretty typical use case. I've been looking at this article and I think it's most of what I need. It uses AspectJ as well as "jcambi aspects" to perform logging.
But I would like to do something like the following:
public void login(User user) {
String userType = user.getType();
if (!user.isActive()) {
// point cut 1 -- log inactive user
} else if (!user.isPasswordValid()) {
// point cut 2 -- log wrong password
} else {
// point cut 3 -- log successful login
}
}
We have an established log format. Something like:
<actor>|<action_code>|<error_code>|<extra_info>
All of the Actor types, Actions and Error Codes are contained in enums.
Is there any way to tell AspectJ to :
log within 'ifs', and log different info, depending on what happened? for example, in point cut 1 log one of the following:
admin|login|001|Admin user inactive
user|login|001|Normal user inactive
... and in point cut 2 log one of the following:
admin|login|002|Invalid Admin password
user|login|002|Invalid normal user password
... and in point cut 3 log one of the following:
admin|login|000|Successful Admin login
user|login|000|Successful Normal user login
Something tells me it is not possible. Or at least not easy. But I'm not sure if it's even worth attempting. So I'm torn. On the one hand I'd like to "sanitize" my code of all logging. On the other hand, I'm not sure if it's going to be too much work to implement this.
Any ideas?
*************************************** EDIT ***************************************
Thank you both for your answers! I realize now two things: 1. I've got a lot of work ahead of me. And 2. I think I put too much emphasis on the "login" example.
Login is just one tiny use case. My task is to add logging everywhere ... in a bunch of methods in many, many classes. Basically everywhere I see a LOG.debug() or LOG.info(), anywhere in the application, to replace it with Aspect logging. This also means that as much as I'd like to, I can't just refactor all of the code to make my life easier. I'd love to make login use Exceptions but it's beyond the scope of my task: add logging.
And of course, in each method the business logic will be different, and as such, so will the logging. So my question becomes: what's the best practice to do this? I mean, each method will have its own logic, its ifs ... and will log different things conditionally. So do I go ahead and create an aspect class for each one of these use cases and basically have the same "ifs" there as well?
An example (that's not login!): A method that imports data.
public void import(String type) {
if (type.equals("people")) {
try {
int result = importPeople();
if (result > 0) {
// do some stuff
LOG.info("ok");
} else {
// do some stuff
LOG.info("problem");
}
} catch (Exception e) {
// do some stuff
LOG.debug("exception ...");
}
} else if (type.equals("places")) {
try {
int result = importPlaces();
if (result > 0) {
// do some stuff
LOG.info("ok");
} else {
// do some stuff
LOG.info("problem");
}
} catch (Exception e) {
// do some stuff
LOG.debug("exception ...");
}
}
}
Mind you it's a crap example, with repeated code, etc. But you get the idea. Should I also create an "import" aspect, for logging this method ... with all the accompanying "ifs" to log "ok", "problem", "exception" ? And do this for every use case?
I'm all for getting rid of intrusive logging code but ... it seems like something of a code smell to have to have the logic, with its "ifs", etc., both in the original method (because the method is "doing more stuff" than logging) as well as in the corresponding Aspect ...
Anyway, you both answered my original question ... but I can only have 1 be the answer, so I'm going to accept kriegaex's because he seems to have put a lot of work into it!