Blogs
Although not publicly known, you can drop the use of the Liferay logging facilities and use SLF4J instead.
Introduction
So for the longest time I have been an advocate of Liferay's logging API. Folks have asked how to use Log4J or other frameworks and I've always advised against it.
Why?
Well, for 3 primary reasons:
- Liferay uses it. As with all things Liferay, it is always easier to go with flow than it is to fight your way upstream.
- It can be controlled by the Liferay Logging panel of the Server Administration control panel, so it is super easy to enable additional logging while the server is live.
- A separate logger can result in a split log, with your application messages going one place but any calls to the Liferay APIs will have messages going to another location.
For these 3 reasons, it was always clear to me that using Liferay's logging API was really the only good choice.
The problem with this, however, has always been 3rd party dependencies. They always wanted to use Log4j directly or some other logging framework, so getting them all to play nicely w/ Liferay's logger was sometimes a miserable chore.
As of Liferay 7.0+, though, there was a new alternative introduced that would make it a heck of a lot easier to log from custom code as well as support logging from 3rd party frameworks - SLF4J.
SLF4J and Liferay
You can find a brief intro to using SLF4J with your Liferay custom code here: https://dev.liferay.com/en/develop/tutorials/-/knowledge_base/7-0/implementing-logging
The missing info, for me anyway, was just how to get it all wired up correctly to work in OSGi.
For that, you will need to add as a dependency for your project the slf4j-api module. In Gradle, you add the following:
compileOnly group: 'org.slf4j', name: 'slf4j-api', version: '1.7.26'
For Maven, you'll add:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.26</version> <scope>provided</scope> </dependency>
Note that you are not going to be including the SLF4J API jar directly into your module, otherwise you'll end up with unresolved reference errors on the org.slf4j.impl package.
Also note that you will not be including any static SLF4J binding module into your project; Liferay actually provides the SLF4J binding that outputs into the standard Liferay logs.
Conclusion
So now that we know how to use SLF4J instead of the Liferay logger, what are the reasons why we would want to?
- Liferay uses it. Seriously, there has been a shift underway in the Liferay code to adopt the SLF4J API instead of directly using the Liferay loggers.
- It can be controlled by the Liferay Logging panel of the Server Administration control panel. Seriously, this is still a feature even when using SLF4J.
- Since it is a standard logging framework, it has much wider adoption amongst 3rd party dependencies and is much easier to integrate.
- Legacy code can still use the Liferay logger, so current code will continue to work unchanged.
- Liferay actually recommends using the SLF4J API over the Liferay logger. At some point they may want to switch from the legacy Log4j logger, and by using the standard SLF4J API your code will be more resilient to that change if/when it happens.
So you get a newer, updated logging API with support for formats, varargs, but you also still get the classic features of Liferay logging so you can dynamically change logging on the fly.
I should note that my other previous blogs about logging also still apply when using SLF4J:
https://community.liferay.com/blogs/-/blogs/liferay-7-dxp-making-logging-changes-persistent for making the Server Administration logging panel changes persist across restarts.
https://community.liferay.com/blogs/-/blogs/centralized-liferay-logging to add a JSON-based output logger that is perfect for consuming in an ELK stack.

