Java logging configuration for dependencies and transitive dependencies - java

Scenario I have:
project --> libA --> libB
project uses libA (imported in pom), libA uses libB.
Due to other constrains, in project pom I exclude everything from libA and then I import manually libB.
Both libA and libB are maintained by me but are extracted as librarie for reusability. Project and libB have as parent the sprig-boot-parent. libA is a maven project (no parent) that contains spring libraries.
If I put logback.xml file in all of them (project, libA, libB), then I receive an warning:
13:20:26,442 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs multiple times on the classpath.
Additional to above log, there are other lines of log that I don't desire.
If I put logback.xml in project and in libB, then I don't receive the above warning. The logs in the project and libB is formated correctly but not the one in libA
In the end I want to have the same log format for all of them without other unwanted logs.
How can I cofigure logback so that it will apply also to the library and transitive libraries ?
What are the recommendations in these types of scenarios?
Later edit:
Adding logback config that is applied in the project:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<encoder>
<pattern>D:%d{yyyy-MM-dd HH:mm:ss.SSS} L:%p C:%c{1} F:%F\(%L\) Fn:%M T:%thread R:%X{R} - %m%n</pattern>
</encoder>
</appender>
<appender name="pandaAppender" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<encoder>
<pattern>L:%p %m%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="stdout"/>
</root>
<logger name="com.happypanda" level="INFO" additivity="false">
<appender-ref ref="stdout"/>
</logger>
<logger name="com.happypanda.myproject" level="INFO" additivity="false">
<appender-ref ref="pandaAppender"/>
</logger>
<logger name="com.happypanda.libB" level="INFO" additivity="false">
<appender-ref ref="pandaAppender"/>
</logger>
<logger name="org.apache.http" level="ERROR">
<appender-ref ref="stdout"/>
</logger>
<logger name="org.apache.http.wire" level="ERROR">
<appender-ref ref="stdout"/>
</logger>
</configuration>
Later later edit:
I've tried to simplify the logic: to remove the libA and use directly libB in project.
Now the log level in libB is debug + there are additional logs from httpclient (see this as reference Disable HttpClient logging)
Later later edit:
In my application I'm taking the logback.xml from external source (is not in resources). In a static block I have the following config:
System.setProperty("logging.config", "file:/services/config/logback.xml");
For testing purposes I've moved the config log inside the resources file of the project. Now all the logs in both project and libB are ok.
I've tried to set them as command line properties but doing so I see debug logs in libB.
CMD java -XX:MinRAMPercentage=40.0 -XX:MaxRAMPercentage=80.0 -XX:+HeapDumpOnOutOfMemoryError -Dlogging.config=/services/config/logback.xml -jar

You should create the logback file for the Project, which is using library A and library B.
In this logback configuration files, you need to handle the log which the project requires and you need: project classes and library classes.
Since you are using logback in this project, I suggest you to specify the dependency and its version in its pom.xml, so Maven is going to use the version from the POM of Project, and not "guessing libA or libB".

Related

Log SQL to file with logback & hibernate

I am trying to get the SQL logged directly to a file when running the dev profile.
This is my logback.xml
<configuration>
<property name="SQL_LOG_FILE" value="${LOG_PATH:-${LOG_TEMP:-${TMPDIR:-/tmp}}}/${HIBERNATE_LOG_FILE:-hibernate.log}"/>
<springProfile name="dev">
<appender name="SQLDEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${SQL_LOG_FILE}</file>
<encoder>
<charset>utf-8</charset>
<Pattern>%-5level %logger{0} - %msg%n</Pattern>
</encoder>
</appender>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<charset>utf-8</charset>
<Pattern>[%highlight(%p)] [%t] %c - %m%n</Pattern>
</encoder>
</appender>
<logger name="org.hibernate.SQL" additivity="false" level="DEBUG">
<appender-ref ref="SQLDEBUG"/>
</logger>
<logger name="org.hibernate.type.descriptor.sql" additivity="false" level="TRACE">
<appender-ref ref="SQLDEBUG"/>
</logger>
</springProfile>
<root level="${logback.loglevel}">
<springProfile name="dev">
<appender-ref ref="CONSOLE"/>
</springProfile>
</root>
I have removed the prod profile settings for simplicity.
The logger for hibernate is inside the dev profile because I don't want it enabled in prod.
I have tried many combinations of these org.hibernate settings. This version generates SQL logs but only dumps them to console, not the log file. Some general startup information is added to the log file but no SQL.
If I change org.hibernate.type.descriptor.sql to org.hibernate.type there is a lot of stack trace logs that are added directly to the file, but no SQL.
Some posts recommend using org.hibernate.SQL level=TRACE but that did not seem to change anything.
I also tried putting the logger outside of the dev profile but that also did not change the results.
There is a lot of information for enabling logback & hibernate for simple console output but not for sending the SQL to its own log file.
I also tried enabling hibernate.SQL=DEBUG in IntelliJ but that makes a lot of SQL on the console, I need to not do that.
I have been try
I doubt you spring profile is being used. To get this to work rename the logback.xml file to logback-spring.xml, allowing the springProfile tag to be used. In this tag, a name can be provided that can be set via properties, environment variables, or VM options. Below is how you can set the springProfile name to dev , which has been used to represent a development environment.
To set in application.properties or as an environment variable:
spring.profiles.active=dev
Or as a VM option:
-Dspring.profiles.active=dev
Also, modify your root-level tag to be inside the spring profile tag:
<springProfile name="dev">
<root level="${logback.loglevel}">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>

How to extract output of retire.js into a file from maven execution

I am using retire.js plugin in maven pom file. The vulnerability details are listed along with the build output.
I would like to extract the retire.js output into a separate file.
Can you please suggest some ways to extract only retire.js data into a file.
Looking into the source code of retire.js Maven plugin we can notice that the log output from retirejs is redirected into Maven's stream (in initMiniLog()). And there seem to be no specific configuration for it.
However, with a bit of tweaking we can set up Maven to gather these logs. So I can suggest the following:
1) By default Maven uses slf4j-simple logger, remove its jar from {M2_HOME}/lib.
2) Place in the same folder a logging library that supports output into files, for example Logback: logback-classic-*.jar and logback-core-*.jar.
3) Define a configuration that will output everything into stdout and only the things that you are looking for into the file. logback.xml should be placed into {M2_HOME}/conf/logging. For example, I used the following draft configuration to extract the output of maven-compiler-plugin into maven.log in the current folder:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>./maven.log</file>
<encoder>
<pattern>%message%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%level - %message%n</pattern>
</encoder>
</appender>
<!--
specify the package of retirejs: com.h3xstream.retirejs
-->
<logger name="org.apache.maven.plugin.compiler" level="TRACE">
<appender-ref ref="FILE" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
4) Execute your build command...

How to set Spring logging level while testing? [duplicate]

This question already has answers here:
Spring Boot Unit Test ignores logging.level
(6 answers)
Closed 5 years ago.
My Spring Boot testing stack is Maven + Surefire + JUnit4. I am annotating the tests with #RunWith(SpringJUnit4ClassRunner.class).
I have application.properties in my project root with this line:
logging.level.root=INFO
This controls the logging when running the Spring boot app and it works on normal runs.
However, whenever I run any JUnit4 tests, I am spammed by pages of DEBUG output like this:
....
17:43:20.500 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'autoConfigurationReport'
17:43:20.500 [main] DEBUG org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader - Registered bean definition for imported class 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfiguration'
17:43:20.501 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.boot.autoconfigure.condition.BeanTypeRegistry'
17:43:20.502 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'autoConfigurationReport'
....
All this spam makes it almost impossible to see the actually relevant parts. How can I apply the logging levels to test output?
I haven't set any logging explicitly, and according to the docs Logback is used by default.
From a general perspective, you can provide a seperate logback-test.xml-file at the test-resource level. In this file you can add settings regarding the log-level targeted at the output you'd like such as:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</layout>
</appender>
<logger name="com.your.package" level="DEBUG">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="org.springframework" level="WARN">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="org.hibernate" level="WARN">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="org.eclipse" level="WARN">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="jndi" level="WARN">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="org.apache.http.wire" level="WARN">
<appender-ref ref="CONSOLE"/>
</logger>
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
Hope this helps you somewhat on the path to decreasing the log output. More is documented at logback's own page:
https://logback.qos.ch/manual/configuration.html
Its mentioned in the top section:
Let us begin by discussing the initialization steps that logback follows to try to configure itself:
1.Logback tries to find a file called logback-test.xml in the classpath.
2.If no such file is found, logback tries to find a file called logback.groovy in the classpath.
3.If no such file is found, it checks for the file logback.xml in the classpath..
4.If no such file is found, service-provider loading facility (introduced in JDK 1.6) is used to resolve the implementation of com.qos.logback.classic.spi.Configurator interface by looking up the file META-INF\services\ch.qos.logback.classic.spi.Configurator in the class path. Its contents should specify the fully qualified class name of the desired Configurator implementation.
5.If none of the above succeeds, logback configures itself automatically using the BasicConfigurator which will cause logging output to be directed to the console.

Log4j 2 - Deactivate drools logger

I am using Log4j 2 and I am unsuccessfully trying to change the logging level of jBPM/Drools, having it as a reference. The drools class that keeps logging is ExtensibleXmlParser.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
<Logger name="org.drools.core.xml.ExtensibleXmlParser" level="off">
<AppenderRef ref="Console" />
</Logger>
</Loggers>
</Configuration>
If I get it right, ExtensibleXmlParser uses slf4j and Log4j is compatible with sl4j.
Why doesn't this Log4j configuration work? Could someone provide me a working configuration? Should I configure jBPM/Drools logger indendently?
When log4j seems to ignore your tweaks to the log4j.properties/xml file, it most often means you're not fiddling with the right file. It is likely that there is another configuration file in your classpath that gets found earlier and is taken into account.
Search your entire classpath for log4j* pattern and see what comes out (include the contents of .jar files and application server /lib and /ext folders, if any).
If I get it right, ExtensibleXmlParser uses slf4j and Log4j is compatible with sl4j.
"Is compatible" is not equivalent with "is configured to use". SLF4J plugs into appropriate logging framework through the org.slf4j.impl.StaticLoggerBinder class. Search the classpath (best in your IDE) to see what library this class came with. If there is no such class, then SLF4J logs nothing.

Run Logback in Debug

I've recently switched from log4j to logback and am wondering if there is an easy way to run logback in debug mode, similar to log4j's log4j.debug property. I need to see where it is picking up my logback.xml from.
The docs mention using a StatusPrinter to print out logback's internal status, but that would require code changes.
[EDIT]
This has been fixed in Logback 1.0.4. You can now use -Dlogback.debug=true to enable debugging of the logback setup.
-- Old Answer --
Unfortunately, there is no way to enable debugging via a System property. You have to use <configuration debug="true"> in the logback.xml. Please submit a feature request.
This is how I do it. I set a system property called 'log.level', then I reference it in logback.xml.
Edit: The downside is that you MUST have 'log.level' always set. The way I deal with this is to check in my main method and set it to INFO if not already set, be sure to do this before you first logging calls. Then I can override on the command line, and have a sensible default.
Here is how it looks in my logback.xml:
<configuration>
<logger name="com.mycompany.project" level="${log.level}" />
<logger name="httpclient" level="WARN" />
<logger name="org.apache" level="WARN" />
<logger name="org.hibernate" level="WARN" />
<logger name="org.hibernate.cfg.AnnotationBinder" level="WARN" />
<logger name="org.hibernate.cfg.annotations" level="WARN" />
<logger name="org.quartz" level="WARN" />
<logger name="org.springframework" level="WARN" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-16thread] %-5level %-35.35logger{30} - %msg%n</pattern>
</encoder>
</appender>
<root level="${log.level:-INFO}">
<appender-ref ref="STDOUT" />
</root>
</configuration>
You can set the status listener class via system property:
java -Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener ...
See: Logback manual
I could not make it work using the chosen answer. However, the following worked:
java -Dlogback.configurationFile=/path/to/config-debug.xml com.domain.Main
Just add a file (config-debug.xml in this example) somewhere on your server and leave it there when you need to debug. Like the following.
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{dd-MMM-yyyy HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Run your application using the afore mentioned -D parameter.
When things are back to normal, remove the -D parameter and restart your application.
Source: Chapter 3: Logback configuration
Well, It's pretty easy. Either you can use
log.level = debug
inside the application.properties of Spring boot.
or you can also set this in the configuration file of logback.xml
<root level="${log.level}">
<appender-ref ref="ANY_APPENDER" />
</root>
In eclipse you can have multiple run configurations. Open your main class. Go to Debug dropdown on eclipse toolbar and select Debug configurations. Click the New launch configuration icon at the top left. Give your launch configuration a better name. Click the Arguments tab under the name and enter -Dlog.level=debug or whatever you want. Click Close or Debug
You can do this again and specify -Dlog.level=warn for example.

Categories

Resources