Combination View Flat View Tree View
Threads [ Previous | Next ]
Ivo Ivanov
Liferay and Log4J sent to Windows Event Viewer
January 3, 2012 8:28 AM
Answer

Ivo Ivanov

Rank: New Member

Posts: 1

Join Date: December 13, 2010

Recent Posts

1. Preface
It is easy to configure the log categories and levels of Liferay. One needs to adjust the file LIFERAY_HOME/tomcatXXX/webapps/ROOT/WEB-INF/classes/META-INF/portal-log4j-ext.xml. (This if Liferay portal runs within Tomcat, otherwise of course the path must be changed accordingly.) With the latest Liferay's version even the custom categories will be shown in the control panel and it is possible to change the log levels on the fly.
This is all great, but the log is meant for monitoring, isn't it, and if possible should help catching the problems as soon as they occur instead of when the end user reports them. Now, Microsoft came up with the idea of events and the Event Viewer (EV) for means of the applications to report to the system administrator. Luckily, log4j gives the option to configure an appender that will send the log to the Windows' Event Viewer. This article describes how this can be achieved.

2. Log4J
The configuration of log4J is just straight forward. A new appender using the NTEventlogAppender must be added to the configuration and then define which categories should use it. The appender is as follows.

<appender name="NTEvent" class="org.apache.log4j.nt.NTEventLogAppender">
<param name="source" value="<SOME HUMAN-READABLE NAME>" />
<param name="threshold" value="WARN" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}:%L] %m%n" />
</layout>
</appender>

By default we can send every thing to that logger.

<root>
<priority value="INFO" />
<appender-ref ref="ROLLINGFILE" />
<appender-ref ref="NTEvent" />
</root>

Note that the name provided for the source will be needed later on.
3. Binaries
For this whole thing to work there is a JNI implementation needed to translate the Java calls to the Windows native. Here comes the NTEventlogAppender DLL. The latter can be obtained precompiled from Apache or as source and then compiled. There is a version for x86 and x64. Which one to use actually depends on both the OS and the Java version. If the OS is x64, but the Java is x86 then the x86 version of the DLL is needed. If the Java is x64 then the x64 of the DLL is needed, otherwise the Java process will reject it as "not possible to link a 64 bits process to a 32 bits library".
Another thing to keep in mind is that for the Java process to load the DLL, the latter must be on the java.library.path. (For Tomcat the Java library path can be adjusted inside the set.bat script.)
Starting from version 1.2.16 log4j tries to feel the library path and load the correct DLL. At the time of writing Liferay uses log4j version 1.2.15, which loads only a DLL with name NTEventlogAppender.dll.
4. Windows Event Viewer
By implementing the configuration described above one can make the log message from Liferay appear within the Windows Event Viewer. The problem is that they will start with the well known "The description for Event ID 0 from source ... cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted.". The message from Liferay will follow, but I am guessing if the system administrator sees such a message won't be very happy.
To make the EV find the DLL there are two options:
  • put the DLL on the system path (like under system32 or a location pointed to by the PATH);
  • register it within Windows registry.

The first solution might need a restart of Windows if the PATH is extended in order for the EV to pick up the new value. The second solution does not require restart.
For the second solution to work one needs to import the following registry configuration:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\<SOME HUMAN-READABLE NAME>]
"EventMessageFile"="path to NTEventLogAppender.dll"
"CategoryMessageFile"="path to NTEventLogAppender.dll"
"TypesSupported"=dword:00000007
"CategoryCount"=dword:00000006

Notice that here the human-readable name from (1) above appeared in the name of the registry key.
The user account that is used to run the Java process of the container (Tomcat, JBoss, etc.) must have read access to the registry key.
Note that if the event log is monitored from another PC that does not have DLL installed and configured the event messages will still start with the error from above.
5. Location Of NTEventLogAppender.dll
The big question in the whole picture is where to put the log4j DLL. Some put it under /Windows/System32, some keep it under Tomcat's bin folder. I personally am for a location that is stable and not mixed up with the OS. Maybe Tomcat's bin folder or another folder under your site's deployment location whose content is not changed with every new version of the site.
6. Conclusion
With this article I tried to assemble the intelligence I collected by trial and error (hit and miss) and the information I found on the Internet regarding sending the log messages from log4j into the Windows Event Viewer. This is not specific for Liferay and can be applied with small adjustments to other Java applications.
Hope this article helps others.