Set root logging level in application.yml - java

I used an application.properties with Spring Boot (1.3 M1) and started to translate it into a yaml file because it grew more and more complex.
But I have problems translating this into yaml:
logging.level.*=WARN
logging.level.com.filenet.wcm=ERROR
logging.level.de.mycompany=DEBUG
The last two lines are easily translated into this:
logging:
level:
com.filenet.wcm: ERROR
de.mycompany: DEBUG
But how to add the values for the root logging level ? These two approaches failed:
Failed approach 1:
logging:
level: WARN
com.filenet.wcm: ERROR
de.mycompany: DEBUG
Failed approach 2:
logging:
level:
star: WARN
com.filenet.wcm: ERROR
de.mycompany: DEBUG
I read the docs, searched stackoverflow and googled but did not find an example for a valid syntax.

You can use ROOT to configure the root logging level:
logging:
level:
ROOT: DEBUG

If you want level by package, you can use this syntax :
logging:
level:
org.springframework.web: DEBUG
guru.springframework.controllers: DEBUG
org.hibernate: DEBUG
org: INFO

You can even use your classname to configure logging level:
logging:
level:
com.yourorganization.Yourclass: DEBUG

It's an old question, but I just had this problem.
While setting
org.springframework.web: debug
or
org.hibernate: debug
works fine, if you want to do the same for your project files (setting level per package), you have to use wildcards. So, for the example in the question, it would be:
logging:
level:
root: WARN
com.filenet.wcm.*: ERROR
de.mycompany.*: DEBUG
Alternatively, you can set the logging level per class without using wildcards, as shown in torina's answer.

You can log incoming request by creating CommonsRequestLoggingFilter and adding
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG
to application.properties file as explained in detail in this link - https://www.baeldung.com/spring-http-logging
#Configuration
public class RequestLoggingFilterConfig {
#Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter
= new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true);
filter.setIncludePayload(true);
filter.setMaxPayloadLength(10000);
filter.setIncludeHeaders(false);
filter.setAfterMessagePrefix("REQUEST DATA : ");
return filter;
}
}

Related

Is there a way to get list of loaded properties file in SpringBoot application?

I'm facing an issue on only one platform when I'm trying to execute mvn clean install. As part of the build we compile multiple component and last we execute functional testing using wiremock. It is supposed to pick specific configuration from function testing profile and default properties should be picked from application.properties file. But for some reason same code isn't able to find the properties mentioned in these file. So, just wondering if somehow, if I can get the list of properties files being loaded during wiremock ? This will give some clue on why isn't expected properties files are being picked ?
All properties files are located inside :
src/main/resources
And, following from test class.
#ContextConfiguration(classes = SampleFTConfiguration.class)
public class SampleControllerTest{
//test method
}
#ComponentScan("com.xxx.xxx.xxx.ft")
#PropertySource("classpath:application-test.properties")
public class SampleFTConfiguration{
}
Note : I'm not expecting anyone to fix the issue, all I wanted to know, if we can get the name of loaded property files ?
After searching and trying out for a while, looks like ConfigurableEnvironment is what you're trying to find.
The code is pretty simple. However I think it's better to debug and check the configurableEnvironment value directly, so you can adjust the code to your needs (remove filter name, etc).
#Autowired
private ConfigurableEnvironment configurableEnvironment;
#Test
public void getProperties() {
Map<String, Object> mapOfProperties = configurableEnvironment.getPropertySources()
.stream()
.filter(propertySource -> propertySource.getName()
.contains("application-test.properties"))
.collect(Collectors.toMap(PropertySource::getName, PropertySource::getSource));
mapOfProperties.values()
.forEach(System.out::println);
}
the code will printed out
{properties-one=value-for-properties-one,
properties-two=value-for-properties-two}
with my application-test.properties value
properties-one=value-for-properties-one
properties-two=value-for-properties-two
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/env/ConfigurableEnvironment.html
Ok, following the test definition please make sure that:
You should run the test with spring runner (spring extension if you're on JUnit5). So you should place the annotation #RunWith(SpringRunner.class) (or #ExtendsWith(SpringExtension.class) for junit 5)
The property source you're using is application-test.properties. You've said that the properties file is located in src/main/resources but the file name probably implies that it should reside in src/test/resources
To troubleshoot context configuration on app startup (for those who don't have an access to app sources) you can add
logging:
level:
org.springframework.boot.context.config: trace
to your application.yml to get filenames:
2022-10-26 13:29:45.977 TRACE [,,] 16522 --- [main] o.s.b.context.config.ConfigDataLoaders : Loading file [config/application-app.
yml] using loader org.springframework.boot.context.config.StandardConfigDataLoader
2022-10-26 13:29:45.977 TRACE [,,] 16522 --- [main] o.s.b.context.config.ConfigDataLoaders : Loading file [config/application-ppe.
yml] using loader org.springframework.boot.context.config.StandardConfigDataLoader
Adding org.springframework.boot.context.properties: trace doesn't help much though. Some user-defined properties get logged, however others don't.

capture logs in a test

I'm trying to capture bean allocation logs in a test - I've got code that I've tested, and will successfully capture logs from my classes - but when I try to do it on spring classes it is seemingly not working - here is the code I use to try and capture:
LoggerContext context = (LoggerContext) (LoggerFactory.getILoggerFactory());
Logger log = context.getLogger("org.springframework.beans.factory.support.DefaultListableBeanFactory");
log.setLevel(Level.DEBUG);
MyAppender appender = new MyAppender();
appender.setContext( context);
log.addAppender( appender );
SpringApplication newApplication = new SpringApplication( Application.class);
newApplication.run( new String [] {});
Now if I trace in and look at the logger that spring is using - it looks like a completely different style of logger - (its hooked to a logmanager, not a loggercontext) - and go into that and it seems like it might be a different context?
Any idea what I'm doing wrong, and how I can in a unit test capture spring bean creation logs?
Spring boot is using Logback logger by default
It uses LogbackLoggingSystem implementation which
extends from AbstractLoggingSystem
Spring boot LoggingSystem runs before context is initialized
To override default properties you can define logback.xml or logback-spring.xml
Or you can use application.yml or properties file to define log configurations :
logging.level.* : It is used as prefix with package name to set log level.
logging.file : It configures a log file name to log message in file. We can also configure file name with absolute path.
logging.path : It only configures path for log file. Spring boot creates a log file with name spring.log
logging.pattern.console : It defines logging pattern in console.
logging.pattern.file: It defines logging pattern in file.
logging.pattern.level: It defines the format to render log level. Default is %5p.
As documentation says:
You can force Spring Boot to use a particular logging system by using the org.springframework.boot.logging.LoggingSystem system property. The value should be the fully qualified class name of a LoggingSystem implementation. You can also disable Spring Boot’s logging configuration entirely by using a value of none.
If you use static Loggers in your Class under Test, you could use Powermock to mock the logger and assert the output, as descirbed in this question.
We use it in our Spring-Tests and formatting and style is the same.
for anyone interested - this finally worked for me:
Logger logger = Logger.getLogger(
"org.springframework.beans.factory.support.DefaultListableBeanFactory");
logger.addHandler( this );
logger.setLevel( java.util.logging.Level.FINE);
_logger = logger;
now I can capture, trace and time all bean allocations.

Suppress warn logs for exception in Spring Boot

I have a custom exception like this
#ResponseStatus(HttpStatus.UNAUTHORIZED)
public class AccessException extends RuntimeException {
}
But when I throw it from a #RestController, it's logging this:
2018-04-17 11:44:58.239 WARN 17928 --- [nio-8080-exec-3] .w.s.m.a.ResponseStatusExceptionResolver : Resolved exception caused by Handler execution: site.user.AccessException
I tried checking the source code but could not find where this is getting logged. I don't want to turn off logging because it may log other things that I am interested in. I just don't think that a custom exception like this should be logged every time.
You may set log level for class org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver to ERROR. That way you will only loose WARN, DEBUG and TRACE logs for this class only.
If there are some WARN-level exceptions you want to see from this class I see two options:
copy org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver to your codebase, change the logging. Make sure that your copy is on the top of the classpath and Spring is below. This is kind of hack. ResponseStatusExceptionResolver is implementation detail of Spring. It may be changed/moved/deleted in future release.
write your own implementation of org.springframework.web.servlet.HandlerExceptionResolver, register it, make sure that ResponseStatusExceptionResolver is not registered.
In Spring you can add this line into your application.properties to specify logging level for certain class:
logging.level.site.user.AccessException=ERROR
or
logging.level.site.user.AccessException=OFF

What is the best way to disable ehcache in JHipster

I want EHCache in production, but not in development as I tend to fiddle with database records in development.
The only thing I came across after searching is this JVM option to disable cache completely -Dnet.sf.ehcache.disabled=true, but somehow this does not appear to be the ideal solution.
Best would be to have an option in application-dev.yml. I tinkered with timeToLiveSeconds and kept it low (1), but it did not seem to have any effect.
I tried to add an api in my REST service like this, but it did not seem to have any effect either:
/**
* GET /clearCache -> Clear Cache
*/
#RequestMapping(value = "/clearCache",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<String> clearCache() {
CacheManager.getInstance().clearAll();
return new ResponseEntity<String>(HttpStatus.OK);
}
Also, a corollary to this same question, I put a debug breakpoint in CacheConfiguration.java here, but it never seems to get hit.
#PreDestroy
public void destroy() {
Any help is highly appreciated!
Here is my full log on startup with fast boot:
[INFO] mypackage.Application - Starting Application on Lenovo-PC with PID 7408 (D:\projects\app\target\classes started by lenovo in D:\projects\app)
[DEBUG] mypackage.Application - Running with Spring Boot v1.2.4.RELEASE, Spring v4.1.6.RELEASE
[DEBUG] org.jboss.logging - Logging Provider: org.jboss.logging.Slf4jLoggerProvider
[DEBUG] mypackage.config.DatabaseConfiguration - Configuring Datasource
[WARN] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory - HHH020003: Could not find a specific ehcache configuration for cache named [mypackage.Org]; using defaults.
[WARN] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory - HHH020003: Could not find a specific ehcache configuration for cache named [mypackage.Workflow]; using defaults.
[WARN] org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory - HHH020003: Could not find a specific ehcache configuration for cache named [mypackage.Department]; using defaults.
...
...
...
[DEBUG] mypackage.config.MailConfiguration - Configuring mail server
[INFO] mypackage.Application - Running with Spring profile(s) : [dev, fast]
If you look at the CacheConfiguration class, you'll see:
#Profile("!" + Constants.SPRING_PROFILE_FAST)
public class CacheConfiguration {
So if you use fast profile, caching is disabled, so either you use this profile or you change annotation to enable caching only in prod profile.
#Profile(Constants.SPRING_PROFILE_PRODUCTION)
public class CacheConfiguration {
You're right, the ehcache code where the WARN log is issued creates a cache anyway and it does it for your 3 entities: Org, Workflow and Department.
if ( cache == null ) {
LOG.unableToFindEhCacheConfiguration( name );
manager.addCache( name );
cache = manager.getEhcache( name );
LOG.debug( "started EHCache region: " + name );
}
I'm not sure the cache is used for entities as our configuration is not run but anyway even the warning is not satisfying, there's probably something missing in our configuration to avoid it.
Could you please open an issue ?

How can I log SQL statements in Spring Boot?

I want to log SQL statements to a file.
I have the following properties in application.properties:
spring.datasource.url=...
spring.datasource.username=user
spring.datasource.password=1234
spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
security.ignored=true
security.basic.enabled=false
logging.level.org.springframework.web=INFO
logging.level.org.hibernate=INFO
logging.file=c:/temp/my-log/app.log
When I run my application,
cmd> mvn spring-boot:run
I can see SQL statements in the console, but they don't appear in app.log. The file contains only basic logs from Spring.
What should I do to see SQL statements in the log file?
Try using this in your properties file:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
This works for standard output too:
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
To log values:
logging.level.org.hibernate.type=trace
Just add this to application.properties.
This works for me (YAML):
spring:
jpa:
properties:
hibernate:
show_sql: true
format_sql: true
logging:
level:
org:
hibernate:
type: trace
Settings to avoid
You should not use this setting:
spring.jpa.show-sql=true
The problem with show-sql is that the SQL statements are printed in the console, so there is no way to filter them, as you'd normally do with a Logging framework.
Using Hibernate logging
In your log configuration file, if you add the following logger:
<logger name="org.hibernate.SQL" level="debug"/>
Then, Hibernate will print the SQL statements when the JDBC PreparedStatement is created. That's why the statement will be logged using parameter placeholders:
INSERT INTO post (title, version, id) VALUES (?, ?, ?)
If you want to log the bind parameter values, just add the following logger as well:
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace"/>
Once you set the BasicBinder logger, you will see that the bind parameter values are logged as well:
DEBUG [main]: o.h.SQL - insert into post (title, version, id) values (?, ?, ?)
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [1] as [VARCHAR] - [High-Performance Java Persistence, part 1]
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [2] as [INTEGER] - [0]
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [3] as [BIGINT] - [1]
Using datasource-proxy
The datasource-proxy OSS framework allows you to proxy the actual JDBC DataSource, as illustrated by the following diagram:
You can define the dataSource bean that will be used by Hibernate as follows:
#Bean
public DataSource dataSource(DataSource actualDataSource) {
SLF4JQueryLoggingListener loggingListener = new SLF4JQueryLoggingListener();
loggingListener.setQueryLogEntryCreator(new InlineQueryLogEntryCreator());
return ProxyDataSourceBuilder
.create(actualDataSource)
.name(DATA_SOURCE_PROXY_NAME)
.listener(loggingListener)
.build();
}
Notice that the actualDataSource must be the DataSource defined by the connection pool you are using in your application.
Next, you need to set the net.ttddyy.dsproxy.listener log level to debug in your logging framework configuration file. For instance, if you're using Logback, you can add the following logger:
<logger name="net.ttddyy.dsproxy.listener" level="debug"/>
Once you enable datasource-proxy, the SQL statement are going to be logged as follows:
Name:DATA_SOURCE_PROXY, Time:6, Success:True,
Type:Prepared, Batch:True, QuerySize:1, BatchSize:3,
Query:["insert into post (title, version, id) values (?, ?, ?)"],
Params:[(Post no. 0, 0, 0), (Post no. 1, 0, 1), (Post no. 2, 0, 2)]
Please use:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.jpa.show-sql=true
If you have a logback-spring.xml file or something like that, add the following code to it:
<logger name="org.hibernate.SQL" level="trace" additivity="false">
<appender-ref ref="file" />
</logger>
That works for me.
To get bind variables as well:
<logger name="org.hibernate.type.descriptor.sql" level="trace">
<appender-ref ref="file" />
</logger>
For the SQL Server driver (Microsoft SQL Server JDBC Driver), try using:
logging.level.com.microsoft.sqlserver.jdbc=debug
in your application.properties file.
My personal preference is to set:
logging.level.com.microsoft.sqlserver.jdbc=info
logging.level.com.microsoft.sqlserver.jdbc.internals=debug
You can look at these links for reference:
Tracing driver operation
“How-to” Guides, 7. Logging
Translated accepted answer to YAML works for me
logging:
level:
org:
hibernate:
SQL:
TRACE
type:
descriptor:
sql:
BasicBinder:
TRACE
According to documentation it is:
spring.jpa.show-sql=true # Enable logging of SQL statements.
Log in to standard output
Add to application.properties
### To enable
spring.jpa.show-sql=true
### To make the printing SQL beautify
spring.jpa.properties.hibernate.format_sql=true
This is the simplest way to print the SQL queries, though it doesn't log the parameters of prepared statements.
And it’s not recommended since it’s not such as optimized logging framework.
Using a logging framework
Add to application.properties
### Logs the SQL queries
logging.level.org.hibernate.SQL=DEBUG
### Logs the prepared statement parameters
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
### To make the printing SQL beautify
spring.jpa.properties.hibernate.format_sql=true
By specifying the above properties, log entries will be sent to the configured log appender, such as log-back or Log4j.
We can log SQL statements using two approaches in Spring boot:
1: using logger
2: standard approach
For logger
You should add this line to application.properties file:
logging.level.org.hibernate.SQL=DEBUG
Standard Approach
You should add these lines in application.properties file:
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
If you want to view the actual parameters used to query you can use
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql=TRACE
Then notice that actual parameter value is shown as binding parameter...:
2018-08-07 14:14:36.079 DEBUG 44804 --- [ main] org.hibernate.SQL : select employee0_.id as id1_0_, employee0_.department as departme2_0_, employee0_.joining_date as joining_3_0_, employee0_.name as name4_0_ from employee employee0_ where employee0_.joining_date=?
2018-08-07 14:14:36.079 TRACE 44804 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [TIMESTAMP] - [Tue Aug 07 00:00:00 SGT 2018]
We can use any one of these in the application.properties file:
spring.jpa.show-sql=true
Example:
//Hibernate: select country0_.id as id1_0_, country0_.name as name2_0_ from country country0_
or
logging.level.org.hibernate.SQL=debug
Example:
2018-11-23 12:28:02.990 DEBUG 12972 --- [nio-8086-exec-2] org.hibernate.SQL : select country0_.id as id1_0_, country0_.name as name2_0_ from country country0_
For hibernate 6:
it is:
spring.jpa.properties.hibernate.show_sql=true
logging.level.org.hibernate.orm.jdbc.bind = trace
You can simply add the below lines in application.properties for stdout SQL queries:
spring.jpa.properties.hibernate.show_sql=true
Use this code in the file application.properties:
# Enable logging for configuration troubleshooting
logging.level.org.hibernate.SQL=DEBUG
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
If you're having trouble with this setting and it seems to work sometimes and not other times - consider if the times where it doesn't work are during unit tests.
Many people declare custom test-time properties via the #TestPropertySources annotation declared somewhere in your test inheritance hierarchy. This will override whatever you put in your application.properties or other production properties settings so those values you're setting are effectively being ignored at test-time.
Putting spring.jpa.properties.hibernate.show_sql=true in application.properties didn't help always.
You can try to add properties.put("hibernate.show_sql", "true"); to the properties of the database configuration.
public class DbConfig {
#Primary
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean
entityManagerFactory(
EntityManagerFactoryBuilder builder,
#Qualifier("dataSource") DataSource dataSource
) {
Map<String, Object> properties = new HashMap();
properties.put("hibernate.hbm2ddl.auto", "validate");
properties.put("hibernate.show_sql", "true");
return builder
.dataSource(dataSource)
.packages("com.test.dbsource.domain")
.persistenceUnit("dbsource").properties(properties)
.build();
}
You just need to set spring.jpa.show-sql=true in application.properties.
For example, you may refer to ConfigServerRepo/application.yaml.
In my YAML file:
logging:
level:
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql: TRACE
Spring Boot version: 2.3.5.RELEASE
The basic way is to add the following lines in your application.properties. This will enable Spring Boot to log all your SQL queries that get executed:
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
The second line is used to beautify the SQL statements.
If you want to use loggers, you can use the following lines:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
The second line is used to print all the parameters that get bound with your queries.
Add these in the properties. Quoting Hibernate Show SQL:
# Show SQL statement
logging.level.org.hibernate.SQL=debug
# Show SQL values
logging.level.org.hibernate.type.descriptor.sql=trace
If you are using JdbcTemplate, add the below in application.properties file to log SQL and parameter values.
logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE

Categories