How to delegate HornetQ logging to Slf4j
I want that all logging from HornetQ, which runs embedded in my application, is delegated to slf4j. Unfortunately any attempt failed. I allready tried
- added jul-to-slf4j
- installed the bridge
SLF4JBridgeHandler.install();
- Tried the
Log4jLogDelegat开发者_Python百科eFactory
("hornetq-configuration.xml" via<log-delegate-factory-class-name>org.hornetq.integration.logging.Log4jLogDelegateFactory</log-delegate-factory-class-name>
) - Wrote my own
LogDelegate
andLogDelegateFactory
But whatever I do, the folloing lines are not catched:
13.07.2011 17:42:11 org.hornetq.core.logging.impl.JULLogDelegate warn
WARNUNG: AIO wasn't located on this platform, it will fall back to using pure Java NIO. If your platform is Linux, install LibAIO to enable the AIO journal
13.07.2011 17:42:11 org.hornetq.core.logging.impl.JULLogDelegate info
INFO: Using NIO Journal
13.07.2011 17:42:11 org.hornetq.core.logging.impl.JULLogDelegate info
INFO: Started Netty Acceptor version 3.1.5.GA-r1772
Anything I did miss?
I found a complete solution that I want to share with you. I have previously tried each of these on their own, but you have to combine some of the techniques mentioned in other answers.
- You need to write your own LogDelegate:
import org.hornetq.spi.core.logging.LogDelegate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Slf4jLogDelegate implements LogDelegate { private final Logger logger; public Slf4jLogDelegate(Class clazz) { logger = LoggerFactory.getLogger(clazz); } @Override public void debug(Object message) { logger.debug(message.toString()); } @Override public void debug(Object message, Throwable t) { logger.debug(message.toString(), t); } @Override public void error(Object message) { logger.error(message.toString()); } @Override public void error(Object message, Throwable t) { logger.error(message.toString(), t); } @Override public void fatal(Object message) { logger.error(message.toString()); } @Override public void fatal(Object message, Throwable t) { logger.error(message.toString(), t); } @Override public void info(Object message) { logger.info(message.toString()); } @Override public void info(Object message, Throwable t) { logger.info(message.toString(), t); } @Override public boolean isDebugEnabled() { return logger.isDebugEnabled(); } @Override public boolean isInfoEnabled() { return logger.isInfoEnabled(); } @Override public boolean isTraceEnabled() { return logger.isTraceEnabled(); } @Override public void trace(Object message) { logger.trace(message.toString()); } @Override public void trace(Object message, Throwable t) { logger.trace(message.toString(), t); } @Override public void warn(Object message) { logger.warn(message.toString()); } @Override public void warn(Object message, Throwable t) { logger.warn(message.toString(), t); } }
- Then you need to write the factory:
import org.hornetq.spi.core.logging.LogDelegate; import org.hornetq.spi.core.logging.LogDelegateFactory; public class Slf4jLogDelegateFactory implements LogDelegateFactory { // Maybe caching of delegates makes sense? @Override public LogDelegate createDelegate(Class clazz) { return new Slf4jLogDelegate(clazz); } }
- Then add to your hornetq-configuration.xml the following line:
<log-delegate-factory-class-name>yourpackage.Slf4jLogDelegateFactory</log-delegate-factory-class-name>
- Finally, add the following line before you start the embedded server:
org.hornetq.core.logging.Logger.setDelegateFactory(new Slf4jLogDelegateFactory());
I'm just wondering why they can't use proven logging mechanisms, that make it easy to exchange a logger.
Since you are running Embedded, try adding this code before you start the server:
org.hornetq.core.logging.Logger.setDelegateFactory(new YourOwnDelegateFactory())
You had probably a few messages using the old delegate until the server got it from the config.
When trying this, I also found that when HornetQServerImpl
initialized its static log, it does so before loading the new LogDelegateFactory
so instead of using the one I'm specifying on the hornetq-configuration.xml it uses JULLogDelegateFactory
so its logs are directly output to the console.
Diving on HornetQ's code I found that it initializes this on Logger.initialise()
and that also there it looks for a System property named "org.hornetq.logger-delegate-factory-class-name"
to set the default factory, so I used that to fix my problem.
I've fixed this using Spring:
<!-- This property must be set so HornetQServerImpl logger uses our factory -->
<bean id="systemPrereqs" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.System" />
<property name="targetMethod" value="setProperty" />
<property name="arguments">
<list>
<value>org.hornetq.logger-delegate-factory-class-name</value>
<value>my.Slf4jLogDelegateFactory</value>
</list>
</property>
</bean>
精彩评论