Liferay 7/DXP: Making Logging Changes Persistent


I have never liked one aspect of Liferay logging - it is not persistent.

For example, I can't debug a startup issue unless I get the portal-log4j-ext.xml file set up and out there.

Not so much of a big deal as a developer, but as a portal admin if I use the control panel to change logging levels, I don't expect them to be lost just because the node restarts.


So about a year ago, I created the log-persist project.

The intention of this project is to persist logging changes.

The project itself contains 3 modules:

  • A ServiceBuilder API jar to define the interface over the LoggingConfig entity.
  • A ServiceBuilder implementation jar for the LoggingConfig entity.
  • A bundle that contains a Portlet ActionFilter implementation to intercept incoming ActionRequests for the Server Administration portlet w/ the logging config panel.

The ServiceBuilder aspect is pretty darn simple, there is only a single entity defined, the LoggingConfig entity which represents a logging configuration.

The action is in the ActionFilter component. This component wires itself to the Server Administration portlet. All incoming ActionRequests (meaning all actions a user performs on the Server Administration portlet) will be intercepted by the filter. The filter passes the ActionRequest on to the real portlet code, but upon return from the portlet code, the filter will check the command to see if it was the "addLogLevel" or "updateLogLevels" commands, the ones used in the portlet to change log levels. For those commands, the filter will extract the form values and pass them to the ServiceBuilder layer to persist.

Additionally the filter has an @Activate method that will be invoked when the component is started. In this method, the code pulls all of the LoggingConfig entities and will re-apply them to the Liferay logging configuration.

All you need to do is build the 3 modules and drop them into your Liferay deploy folder, they'll take care of the rest.


So that's it. I should note that the last module is not really necessary. I mean, it only contains a single component, the ActionFilter implementation, and there's no reason that it has to be in its own module. It could certainly be merged into the API module or the service implementation module.

But it works. The logging persists across restarts and, as an added bonus, will apply the logging config changes across the cluster during startup.

It may not be a perfect implementation, but it will get the job done.

You can find it in my git repo: