tags:

views:

154

answers:

2

We use this Log4J config to display JTA info:

<category name="org.springframework.transaction">
    <priority value="DEBUG"/>
</category>

The resulting log entries are of the type:

15:36:08,048 DEBUG [JtaTransactionManager] [ ] Creating new transaction with name [class]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
15:36:09,564 DEBUG [JtaTransactionManager] [ ] Initiating transaction commit

... Now we use Spring's MessageListener to listen to an MQ queue. Problem is this is transactional, and we get the aforementioned logging printed out every 2 seconds.

What we want, is just to have these JTA log statements printed out when someone uses our REST API to access services that utilize @Transactional. We don't want the JTA log entries that come from this "polling" MQ listening implementation.

Can you do this?

+2  A: 

You should set the default log level higher than DEBUG in your configuration, then try adjusting the log level for org.springframework.transaction manually in your REST API inside the appropriate call., e.g.

public void doSomething() {
    Logger txLogger = Logger.getLogger("org.springframework.transaction");
    Level defaultLevel = txLogger.getLevel();
    txLogger.setLevel(Level.DEBUG);
    // do my stuff
    txLogger.setLevel(defaultLevel);
}

This means that during the call to your API - but only then - the calls initiated by the MQ listener would also be logged, but AFAIK there is no way to configure different log levels for the same class depending on where it is called from :-(

Update: Another possibility would be to create a custom TransactionManager, which would be just a wrapper for the one provided by Spring. It would forward the calls to Spring and write its own logs. You would use that in your API but the Spring version in the MQ listener. Then you would have two distinct classes, so you could set different log levels. I am fairly sure this is possible, however it may be more hassle to configure and maintain than it is worth...

Péter Török
That's a decent workaround... suppose what I'm looking for is what you say is not available -- to configure different log levels for the same class depending on where it is called from
Marcus
Custom `TransactionManager` is a nice idea. Like you say, might be more hassle than it's worth..
Marcus
+1  A: 

I'm guessing you're using DefaultMessageListenerContainer, is that right? This actively polls the JMS queue, creating a constant stream of transactions.

There is one thing you could try, and I hesitate to suggest it, but you could consider using SimpleMessageListenerContainer instead. This doesn't poll JMS, it relies on JMS to deliver messages to it instead. This is simpler (hence the name), but less reliable in some JMS setups. Since it's more passive, it'll generate less transaction load, and hence less log noise.

I hesitate to suggest it because changing your design to reduce log noise is probably not a good idea.

skaffman
Our class implements `MessageListener`. That's the extent of my knowledge.. definitely seems to be polling. Using `SimpleMessageListenerContainer` sounds like a good idea.. but as you mention, not sure if we want to change our design. We've used the current approach successfully on other projects, not sure I want to try something new just for more convenient logging options..
Marcus
@Marcus: That's probably wise. Incidentally, the `MessageListenerContainer` is the glue-logic Spring component that links your application's `MessageListener` to JMS.
skaffman