Background
The application in question is a Java web-app deployed in Tomcat and uses Apache CXF for exposing REST services. I found Spring configuration, but not sure how well it is wired up to the CXF infrastructure.
Every time something important happens, like an entity is updated or deleted, I'd like to log information including (but not limited to):
- What happened
- Who made the request
- What entity was changed
- New state of the entity if applicable
- Information about any notification emails sent
- etc...
Current Setup & challenge
We have several layers and the calls look like this: Controller > Service > Data Layer > Utils (Email, SMS sending etc...).
The problem is, the data I want to gather and log, begins to be available and is only available in separate layers. Some times the data is passed through arguments to the next layer, but other times they are not passed because the data isn't required in other layers. Here are some examples:
- Some HTTP request related data is only used for some validation, and is not sent to the service layers.
- Some times, core entity data is only available in service and data layers and isn't available to the controllers.
- Various layers of Utils generate some final pieces of data (like links, codes, final email content) that isn't known to any other layer.
But I need to gather such information from across all layers and log them for audit purpose, as a single log line.
Constraints
- The code is not designed well in terms of respecting layer boundaries. So, sometimes things are passed around where the shouldn't. But I can't continue to do this.
- I can't return all the required data to the controller and finally log them there, because the intermediate layers' methods are called in a lot of places, and is not practical to refactor them all.
- I can't log them in different places separately as the requirement doesn't allow that. If there isn't any other way, I can push this strategy and have a common request ID or something and multiple log lines, to correlate them.
My question is, how and where should I gather all this data and write them to the audit log? What is the best practice for doing the above, in a Java web application?