I have a simple spring MCV application (spring-webmvc 5.0.6) and when running I can see the logs are printing.
My question is how to enable Debug log level. Currently I haven't add and log4j property file but I can see the logs are printing in INFO level.
I tried to find answers to this simple question, so far was not able.
My pom.xml file dependency section has following dependencies.
spring-webmvc (5.0.6.RELEASE)
servlet-api (2.5)
jstl (1.2)
Any help with this would be appreciated.
Since you said that you didnĀ“t provide a logging-implementation, Springs variant of Commons Logging API will only find Java.util.logging (JUL) from the JDK (see Spring Documentation)
By the way: Level.DEBUG in Terms of JUL would be Level.FINE or Level.FINER (see this Articel Log Levels)
Assuming that your app is running on a Tomcat-Server you might edit one of the following files to see Level.FINE on the Console:
Just add:
java.util.ConsoleHandler.level=FINE
org.springframework.level=FINE
${java.home}/lib/logging.properties (global loggin-properties of JRE)
${catalina.base}/conf/logging.properties (global logging-properties of Tomcat)
WEB-INF/classes/logging.properties (webapp-specific logging-properties)
Related
This question already has an answer here:
Can't override java.util.logging.LogManager in a Spring Boot web application: Getting java.lang.ClassNotFoundException on already loaded class
(1 answer)
Closed 10 months ago.
I'm running Tomcat as an embedded server inside of a Springboot app, so all the additional functionality in JULI such as multiple class loaders etc is not needed and just gets in the way.
I just want my app to use java.util.logging directly without the extra complication of JULI. I want a flat configuration where everything just flows directly to java.util.logging and the way I have configured it.
How can I ditch JULI?
UPDATE
The actual problem I'm having is that I'm unable to load a custom Handler... getting a ClassNotFound. I initially thought this was caused by JULI but really seems to be related to Spring Boot's System Class Manager unwillingness to load classes from BOOT-INF.
JULI is just a logging facade used by Tomcat for its internal logging (cf. javadoc) based on Apache Commons Logging. It is not a logging framework and does not perform any logging by itself.
By default it uses java.util.logging plain and simple the way you configured it.
The additional functionality you can find in a standalone Tomcat (per classloader configuration, multiple handlers of the same class, etc.) is provided by ClassLoaderLogManager. In order to use it you need to set:
-Djava.util.logging.logmanager=org.apache.juli.ClassLoaderLogManager
as JVM parameter (anywhere else it will be probably ignored).
Tomcat's startup scripts add the above mentioned Java system property, but your Spring Boot application almost certainly does not. Hence your application is using java.util.logging plain and simple (unless you are using spring-boot-starter-logging in which case java.util.logging is redirected to LogBack).
TL;DR: by default Tomcat JULI simply forwards messages to java.util.logging. There are no complications.
I am using log4j2 in my spring boot application. This works in all respects re: excluding slf4j, including log4j2, etc.
But when the application deploys I need to customize the file for each target host. I have created an ansible role that does this. Ultimately I end up with a log4j2.xml file deployed in another directory e.g. /prod/produsrX/data/log4j2.xml.
I am using the spring-boot-maven-plugin "repackage" goal to generate an executable jar file. It doesn't seem like that should matter but it is a data point in the problem.
This was supposed to be the easiest part of the project. Always before I have just been able to set -Dlog4j.configurationFile - advice which is echoed on about 3,000 web pages and DOES NOT WORK in Spring Boot 2.1.3.
The most useful info I've found is this question. It talks about using -Dlogging.config because logging must be initialized before other properties are read. Unfortunately that didn't help either.
I did find one example that suggested specifying the above directory in a -classpath parameter to java. But that didn't help either.
Does anyone know how to get a spring boot application to read the log4j2.xml file?
The property actually has to be put into the application context (e.g. application.yml). Using a -D property does not work!
logging:
config: /prod/produsrX/data/log4j2.xml #fully qualified name to your log4j.xml
I hope you can solve this very mysterious puzzle!
After migrating to Java8 and Tomcat8, the logging info on the servers is ok, but there is no logging information on the developer laptops. Adding Spring-boot-starter-log4j2 there is logging info on the laptops but NOT on the servers. How come? How to fix?
In the parent.pom both the dependencies slf4j-api, the slf4j-log4j binding and the 'slf4j : jcl-over-slf4j' are used. In the project there are no log4j.properites files. In all places where spring boot is used, the spring-boot-starter-logging is excluded.
Scenario 1:
On laptops - the SLF4J combination produces NO logging. I guess that is because there are no log4j.properties files. On the servers this combination shows logging. How can this be? Can there be a provided Tomcat configuration that allows this logging?
Scenario 2:
When I add the spring-boot-starter-log4j2, then I get logging on my laptop. On the server there is no logging at all.
You can define general logging settings in your tomcat environment. This is for example shown in this article.
In short: (1) add an extra library and (2) add a default log4j.properties file.
I am using Maven and Spring Boot. I run the application using mvn spring-boot:run.
https://flywaydb.org/documentation/plugins/springboot says Flyway should be called on Spring Boot start.
So my pom.xml contains the dependency to Flyway.
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>4.1.2</version>
</dependency>
The first time I ran the Maven command above it downloaded Flyway stuff, so I think the dependency is working.
I have the following files:
./src/main/resources/db/migration/V123__foo.sql
./src/main/resources/application.properties
The above article implied it should "just work", but I don't understand where it would find the JDBC URL to the database. So I added the following to the application.properties file:
flyway.url=jdbc:postgresql://localhost:5432/services?user=postgres&password=postgres
flyway.enabled=true
When Spring Boot starts up (and loads and makes available my web application) there are no logs from Flyway. I think Flyway is ignored.
What can I do? Or, more generally, how would I go about debugging this problem myself?
Nobody has posted an answer so I'll post what I found out.
M. Deinum was indeed correct in their comments to the question, the problem was a lack of a data source.
My original question was what the approach should be to debugging this kind of issue. Obviously one option is to post to stackoverflow :) But I wanted to know how to do it myself.
Spring Boot has a number of classes which look at your code and classpath, and act appropriately. For example, there are classes providing implementations to the rules like "if Flyway is on the path, and there is a data source, then execute Flyway". That rule wasn't getting triggered in my case, because I had no data source.
It's not the case that the code you write calls Spring Boot, it's the other way around, Spring Boot (external to your code) inspects your code and decides what to do based on rules. This architecture is known as action at a distance. The main problem with action at a distance is it's very difficult to debug.
The only real way to find the solution, and it was the way I went about confirming M. Deinum's diagnostic, is to read the Spring Boot source code and understand the annotations which are used to create Spring Boot code.
From the source code to Spring Boot's Flyway integration we see
#ConditionalOnClass(Flyway.class)
#ConditionalOnBean(DataSource.class)
This means "this code will get executed if Flyway is on the classpath, and if there is a DataSource bean available; otherwise it silently won't get executed".
So the answer to the question "how to debug this problem" is that there is no mechanism other than to read the source code of Spring Boot and find out how it works.
If you want to avoid this sort of problem, you have to avoid frameworks which work via "action at a distance", and that includes Spring Boot.
I am looking at externalizing certain configuration parameters for ehcache in our Grails application and I am running into something not working that the documentation claims ought to.
Likely there is something I am missing.
I am using the grails ehcache plugin version 1.0.1 with Grails 2.4.0 and grails cache plugin 1.1.7. I am using hibernate plugin 3.6.10.16.
Here's what I have in my CacheConfig.groovy configuration...
...
cacheManagerPeerProviderFactory {
peerDiscovery 'automatic'
factoryType 'rmi'
multicastGroupAddress '${ehcacheMulticastGroupAddress}'
multicastGroupPort '${ehcacheMulticastGroupPort}'
timeToLive 'site'
}
I've turned on debug-level logging so I can see what XML it generates. Here's the relevant snippet:
<cacheManagerPeerProviderFactory class='net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory'
properties="peerDiscovery=automatic,multicastGroupAddress=${ehcacheMulticastGroupAddress},multicastGroupPort=${ehcacheMulticastGroupPort},timeToLive=32"
propertySeparator=','
/>
The grails ehcache plugin documentation has the following note, which I was hoping to "prove out"...
(note that ${ehcacheMulticastGroupAddress} and ${ehcacheMulticastGroupPort} are an Ehcache feature that lets you use system property names as variables to be resolved at runtime)
Great. Except that it doesn't work when I start the application. It fails to create CacheManagerPeerProvider due to the following
...
Caused by UnknownHostException: ${ehcacheMulticastGroupAddress}
->> 901 | lookupAllHostAddr in java.net.InetAddress$1
...
I have a myApplication-config.groovy file living in an accessible area that I point to when assigning a value to grails.config.locations in Config.groovy. But I am not sure it is making any effort to really interpolate that value at all.
I tried double quotes but they were a bad idea as well -- at the time of interpreting CacheConfig.groovy it doesn't see the configuration I put into myApplication-config.groovy. I do know it reads that file in successfully at some point because I successfully use it to drive some Quartz job logic, so the placement of that config file is probably not the issue.
The answer is that I need to set SYSTEM PROPERTIES for ehcache to find. Using Grails configuration files such as myApplication-config.groovy is completely incorrect.
The CacheConfig.groovy file is correct, as is the XML it generates. So the question becomes, how do the properties it looks for get set correctly in the first place?
I am deploying to Tomcat. For Tomcat, setting system properties makes the most sense in a setenv.bat file (or setenv.sh on *nix).
I created setenv.bat, put the following into it
set CATALINA_OPTS=%CATALINA_OPTS% -DehcacheMulticastGroupAddress=230.0.0.1 -DehcacheMulticastGroupPort=4446 -DehcachePeerListenerPort=40001
...And it worked. Ehcache was able to find the system properties and start everything appropriately.
tl;dr: system properties != grails application config