开发者

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 and LogDelegateFactory

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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜