I am using atomikos v3.7.0 TransactionEssentials in a stand-alone java app (v1.6) running on Redhat Linux. Everything was and still is working smoothly except that all of a sudden atomikos is churning out logs to the console. I try many things, not sure what caused this and no clue how to control this. Yes, I have seen the link (How to set Atomikos to not write to console logs?)) but that was not useful to me. The java app uses a message driven poj and spring's DefaultMessageListenerContainer, listening to queue for messages and updating MySql database. When the listener is started it prints out the following logs even when no messages are received and the app is supposed to be doing nothing:
createCompositeTransaction ( 300000 ): created new ROOT transaction with id 192.168.252.15.tm0000100002
commit() done (by application) of transaction 192.168.252.15.tm0000100002
createCompositeTransaction ( 300000 ): created new ROOT transaction with id 192.168.252.15.tm0000200002
commit() done (by application) of transaction 192.168.252.15.tm0000200002
createCompositeTransaction ( 300000 ): created new ROOT transaction with id 192.168.252.15.tm0000300002
Now when the listener is shut down and restarted again, it prints logs below as well, in addition the ones above:
Local heuristic termination of coordinator 192.168.252.15.tm1200000016
with state COMMITTING Local heuristic termination of coordinator
192.168.252.15.tm1200100016 with state COMMITTING Local heuristic termination of coordinator 192.168.252.15.tm1200100016 with state
COMMITTING Local heuristic termination of coordinator
192.168.252.15.tm1200200016 with state COMMITTING Local heuristic termination of coordinator 192.168.252.15.tm1200200016 with state
COMMITTING Local heuristic termination of coordinator
192.168.252.15.tm1200300016 with state COMMITTING
Is anything wrong? How do I get this stopped?
I was able to stop the never ending logs, when I swiched to slf4j (over log4j) and by using
<logger name="atomikos">
<level value="error" />
</logger>
Thanks.
Or, you could stay on log4j and specify: log4j.logger.atomikos=ERROR
in my situation it doest't works because there a conflict by library
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/Spidly/WEB-INF/lib/slf4j-jdk14-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/Spidly/WEB-INF/lib/slf4j-log4j12-1.5.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/Spidly/WEB-INF/lib/weld-osgi-bundle-1.0.1-SP3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
i solve it leaving that multiple bindings on pom.xml
Related
Our app has 3rd party code that uses JUL to log. Our app has the jul-to-slf4j.jar on the classpath. I see the SLF4JBridgeHandler.install() method gets called (several times) as for whatever reason spring cleans up logging config a few times on based on certain ApplicationEvents. I created an event listener on ApplicationStartedEvent to again make sure the handler is installed as late as possible. I verify by checking the SLF4JBridgeHandler.isInstalled() method. Yet the 3rd party logs keep flowing to standard out. If i breakpoint the 3rd party logging class in IntelliJ and call SLF4JBridgeHandler.isInstalled() it returns false. If I then execute the below code the logs get picked up by slf4j and everyone is happy.
SLF4JBridgeHandler.install();
LogManager.getLogManager().getLogger("com.3rdparty").setUseParentHandlers(false);
Why does SLF4J keep getting uninstalled? How do I keep it installed? Are the 3rd party loggers getting created before we install slf4j and then not getting updated by the install() call?
Why does SLF4J keep getting uninstalled?
Most common reason is there is code calling LogManager.reset(). You can find the source by using a security manager.
If you user a logging.properties file then just add the bridge as a handler. That way reset is actually installing the bridge handler.
handlers= java.util.logging.ConsoleHandler, org.slf4j.bridge.SLF4JBridgeHandler
The only downside is that the bridge handler has to be visible to the system classloader. A very hacky trick you can try is to subclass SLF4JBridgeHandler and override equals to return false. LogManager.reset won't be able to remove this handler.
Logger.getLogger("").addHandler(new SLF4JBridgeHandler() {
public boolean equals(Object o) { return false;}
});
Are the 3rd party loggers getting created before we install slf4j and then not getting updated by the install() call?
You'll have to do some work to find out that answer. Use JConsole Mbeans or the system out debugging to walk the logger tree while debugging your application. The security manager tracing is your best bet for finding the exact stacktrace for who is responsible for removing the handler.
Can there be two root loggers somehow?
That can't happen under the standard LogManager. Tomcat has an implementation that is sensitive to the context classloader. That LogManager may return different instances of the same logger name based on context class loader. The only other way the handlers can be removed without going through the security manager is if the root logger was garbage collected. You could try to hold a strong reference to the root logger but that really shouldn't be needed. You should print the identity hash code of the root logger when the handler was known to be added and the identity hash code of the root logger after the handler was dropped. If the values are different the logger was garbage collected.
Versions:
Spring: 5.2.16.RELEASE
Spring Integrations: 5.3.9.RELEASE
macOS Big Sur: 11.6
For a fuller account of my spring-integration configuration, see this question I posted yesterday.
To sum up, I have set up this channel for polling changes to a directory:
<int-file:inbound-channel-adapter id="channelIn" directory="${channel.dir}" auto-create-directory="false" use-watch-service="false" filter="channelFilter" watch-events="CREATE,MODIFY">
<int-file:nio-locker ref="channelLocker"/>
<int:poller fixed-delay="${channel.polling.delay}" max-messages-per-poll="${channel.polling.maxmsgs}"></int:poller>
</int-file:inbound-channel-adapter>
It works fine. However, there does not appear to be a configuration option to start the polling after application-start by some arbitrary delay. In my case, I don't think there is any program error (yet) in starting the polling service immediately after Tomcat container starts my war-file. But it is also true that there is quite a bit going on during the application-start, and my preference would be to defer the inception of the polling service some time after the bean for SourcePollingChannelAdapter is created.
Is there anyway to do this in Spring?
There are (at least) a couple of options:
Instead of fixed-delay, use the trigger property to point to a PeriodicTrigger bean with an initialDelay (and fixedDelay).
Set auto-startup="false" and start the adapter manually either directly, or using a control bus.
https://docs.spring.io/spring-integration/docs/current/reference/html/system-management.html#control-bus
We have JTA transactions(Atomikos) configured using Spring annotations across different places in our application. I need to get trace logs whenever a transaction started and completed.
For example, whenever the below method invoked within a new transaction,
#Transactional
void createAgent() { ... }
I need to log a message saying
Transaction started on AgentFactory::createAgent() ...
Transaction ended on AgentFactory::createAgent() ...
Can you please provide if there is any way to enable trace logging on transactions?
If you set loglevel to DEBUG or TRACE for org.springframework.transaction
you get the log entries you want. May be not in the exact format, but the information is provided.
I have a stand alone application that uses File inbound channel adapter to poll for a file from a Specified location at certain interval.
I don't have a taskScheduler instance defined.
When running the application with both Spring integration 2.2.0 and 3.0.2, I see that there are 10 threads created with name task-scheduler-x after certain amount of time. I believe this is the default behavior.
I removed the file inbound channel adapter configuration from my application and re-run it, I noticed the following behavior.
In 3.0.2 , 10 threads are getting created with name task-scheduler-x.
In 2.2.0, Though a taskScheduler instance is getting created (I can see the message about the bean creation in the logs), I don't see any threads getting created with the name task-scheduler-x.
Why is this behavior different between these two versions? What should I do if I don't want to create a taskScheduler instance or I don't want to create any threads for task scheduling?
Thanks for the help.
The framework now has a built-in component (header channel registry) that uses the taskScheduler.
It's not really using many resources although it does have this side effect of instantiating the scheduler thread pool.
We'll look at adding an option to disable it if you don't need/use it. In the meantime, you can revert to the pre 3.0 behavior by adding this bean to your context:
<bean id="integrationHeaderChannelRegistry" class="org.springframework.integration.channel.DefaultHeaderChannelRegistry">
<property name="autoStartup" value="false" />
</bean>
I opened a JIRA Issue for this.
Using the pretty standard stack of CFX and Spring for JAX-RS rest endpoints. I am also using DBCP for database connection pooling. Everything runs inside a tomcat container as a standard web-app. The issue I am trying to solve is to log a consistent thread-id on every log line. That way I can track a request end to end.
But the problem seems to be that Spring/DBCP is switching the thread to a different one, so the log line has thread ids all jumbled up. I can't track a single request end-to-end as a result.
Below is an example
2014-07-22 18:55:47,224 INFO ajp-bio-8034-exec-8 <log_line_omitted>
2014-07-22 18:55:47,226 INFO pool-10-thread-77 <log_line_omitted>
2014-07-22 18:55:47,299 INFO ajp-bio-8034-exec-8 <log_line_omitted>
As you can see, the thread id has changed from ajp-bio-8034-exec-8 to pool-10-thread-100 and back again.
Most likely the thread-id is switching because of the database connection pooling by DBCP.
What can I do go get a consistent view of the request end-to-end?
The log4j properties file uses the following layout
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %p %t %c - %m%n