tags:

views:

314

answers:

3

I've written a custom log4j appender that creates a new Solr document for each log entry and I'm having problems deploying it to JBoss.

The source is viewable on github but the real problem is trying to use the appender from JBoss.

The relevent bits of jboss-log4j.xml look like this:

<appender name="SOLR" class="com.stuartgrimshaw.solrIndexAppender.SolrIndexAppender" />

<root>
   <priority value="${jboss.server.log.threshold}"/>
   <appender-ref ref="CONSOLE"/>
   <appender-ref ref="FILE"/>
   <appender-ref ref="SOLR"/>
</root>

The dependencies for Solr are all available in the .war file that's supplied, but I'm guessing that when the appender is initialised quite early on in the boot process, that application hasn't been deployed yet, which is why I see this error in the log:

2009-11-29 10:40:57,715 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] (main) Error installing to Create: name=jboss.system:service=Logging,type=Log4jService state=Configured mode=Manual requiredState=Create
java.lang.NoClassDefFoundError: org/apache/solr/client/solrj/SolrServerException

Is there any way I can delay the initialization till the solr app has been deployed, or is there a way to deploy the Solr app so it's libraries are visible to jboss while it boots?

+3  A: 

I think you could either deploy the Solr libs in server/[jboss-configuration]/lib (in JBoss 4 that is, might be the same in newer versions), then they are available at boot time.

Or don't use the JBoss log4j configuration and define your own log4j.xml in your WAR (either in a JAR in lib or in classes). It will be loaded by the application classloader when it is deployed.

Hans Doggen
I've tried deploying the Solr libs in the lib directory of the profile I want to use, but if I also deploy the Solr web app that gives me their default admin interface, I get other errors which the Solr mailing list suggested was because I had the libs deployed in both places.I could try extracting the libs from the solr.war file and deploying them in <profile>/lib and deploying the rest of the war to <profile>/deploy/
Stuart Grimshaw
Personally, I prefer the second option, where I do my logging at the application level, not the container/server level.
Hans Doggen
+1  A: 

As you've discovered, you'd have to put your JAR into the JBoss config's lib directory in order to refer to its types in jboss-log4j.xml, but this is generally not good practise.

A pretty straightward alternative is to invoke the log4j API programmatically from inside your application. If you have a WAR, then define a ServetContextListener (or something similar) which is invoked when the WAR deploys, and which attaches your appender. Similarly, when undeployed, it detaches the appender.

See the answer to this previous question for how to get started doing this.

skaffman
A: 

I am guessing that this is to manage your log files and make them easier to search, a la Splunk???? However, this feels like a fairly odd way of doing this.. kind of the "look, I can make a dog walk on it's hind legs" kind of thing... Cool, but why would you want to?

I think a much simpler, more robust approach is to a) grab Splunk Free Edition! b) have a seperate process that consumes your log files from disk and send them to Solr using Solr4J.

I think requiring Solr, just to do logging adds a huge level of complexity.

Eric Pugh
When I looked at Splunk, I had the exact opposite reaction, I thought "That's a lot of installation just so I can search a log file" :-)I can see the appeal of Splunk, but for my requirements it's overkill.
Stuart Grimshaw