Thursday, September 06, 2012

Logback NT Event Log Appender

I've been searching the Net for a logback-based Windows event log appender, but couldn't find any. Log4j has a built-in NTEventLogAppender, as stated in http://stackoverflow.com/questions/8945187/logback-and-windows-event-system-integration, but I came across a nice alternative in the form of log4jna (https://github.com/dblock/log4jna), which doesn't require placing native DLLs in a system directory.

So I based my logback Windows event log appender on org.apache.log4jna.nt.Win32EventLogAppender, to speed things up. After some trial and error, I concluded that it is better to manually create the Windows registry keys and setup some values to ensure the implementation works instead of relying on the current user's administrative rights and having the registry keys created during the appender's initialization. So the code is 'simplified'. More info @ http://code.dblock.org/log4jna-log4jerror-could-not-register-event-source-access-is-denied

By default, the log records will be placed under the Application log, which will contain records from other sources/systems. Viewing the records specific to your application will then require great perception or the use of filters. Since I am using Windows 7 (development) and Windows 2008 Standard (testing/production), there can be a dedicated menu item under 'Applications and Services Logs', as shown below:


To create it, just add the following using regedit: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\${Custom_Log_Name}\${Custom_Source} 

Replace
  •  ${Custom_Log_Name} with the value that will be shown under 'Applications and Services Logs'. In my example, is 'MCI-CA'
  • ${Custom_Source} with the source value that you'll need to set and specify in the logback.xml configuration file. In my example, is 'mci' 
Note: The 'source' value of the appender needs to be unique (system-wide).

Next, configure the appender in logback.xml:


    
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n%throwable
        
    

    
     mci
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n%throwable
        
    

 
        
    
    
    
        
    



Whack in the JARs to classpath: jna.jar, platform.jar (both from log4jna zip package), logback-core-1.0.5.jar, logback-classic-1.0.5.jar, slf4j-api-1.6.4.jar

Also, copy Win32EventLogAppender.dll (log4jna) to Window's system32 folder (e.g. C:\Windows\System32) and add a registry value (refer to .reg file in the zip file link at bottom). You can refer to http://code.dblock.org/log4jna-the-description-for-event-id-4096-from-source-log4jna-cannot-be-found for more details.

Then just get the logger instance and start logging away! I've furnished a simple JUnit test as a sample (link below). I used the system property to load a specific logback.xml file e.g. -Dlogback.configurationFile=D:\eclipse-workspaces\indigo-workspace\Sandbox\src\logback.xml

Caveat: The logback appender can be coded to cater for logback 'classic' and 'access', but I only implemented it for 'classic'. See http://logback.qos.ch/manual/appenders.html for more details.

Accompanying files can be accessed here: http://dl.dropbox.com/u/103052906/blog/tech/nt-logback/logback-ntappender.zip
Post a Comment