Spring boot + maven not printing logs on console - java

Running spring boot/java test project using maven through terminal is not printing logs.However when I run the project through Intellij(run configuration), it does print logs.
I have tried enable logging for spring boot by enabling logs in application.yml file but it didn't work. I have also observed that since intellij uses java to run the test project logging works however I am using maven from terminal so it doesn't work.
logging:
level:
root: INFO
org.package INFO
Enable logs in spring boot java project that prints stuff on terminal.

Besides from the indentation, you are missing the:
logging:
level:
root: INFO
org.package: INFO
Also, you can configure the Logback for Spring-Boot, here is how to: logback
Basically, creating a logback.xml file in the resources path, with the content of:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="org.springframework.web" level="DEBUG"/>
</configuration>
Here it is also another great tutorial: here

Related

flyway.properties file not working as pom.xml configuration alternative

I need to set flyway migration and I don't want to put password and username in pom.xml, I created flyway.properties file, but it's not working, I'm getting this error
Failed to execute goal org.flywaydb:flyway-maven-plugin:6.5.1:clean (default-cli) on project entesting: org.flywaydb.core.api.FlywayException: Unable to connect to the database. Configure the url, user and password!
flyway.properties file is in same directory as pom.xml
flyway.user=sa
flyway.password=passwordForThis
flyway.url=jdbc:sqlserver://172.23.176.144;database=DB_Name
flyway.locations=filesystem:src/main/resources/db/migration
flyway.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
pom.xml flyway plugin config:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>6.5.1</version>
<configuration>
<url>jdbc:sqlserver://172.23.176.144;database=DB_Name</url>
<user>sa</user>
<password>passwordForThis</password>
</configuration>
</plugin>
To summarize I don't want to add password, username etc. in pom.xml(that works), I want it to be in flyway.propeties.
Flyway can be configured in a number of ways beyond directly putting it into the maven pom.xml. See documentation on configuring the maven plugin
The contents of the properties file you showed looks like the contents of a flyway.conf file.
Flyway will search for and automatically load the <user-home>/flyway.conf config file if present.
It is also possible to point Flyway at one or more additional config files. This is achieved by supplying the System property flyway.configFiles as follows:
mvn -Dflyway.configFiles=path/to/myAlternativeConfig.conf flyway:migrate
See https://flywaydb.org/documentation/maven/#config-files for more information.
Alternatively for storing the database user and password, Maven settings.xml files can also be used:
<settings>
<servers>
<server>
<!-- By default Flyway will look for the server with the id 'flyway-db' -->
<!-- This can be customized by configuring the 'serverId' property -->
<id>flyway-db</id>
<username>myUser</username>
<password>mySecretPwd</password>
</server>
</servers>
</settings>

how to skip Kafka and zookeeper logs in debug mode

Using spring boot application.yml and logback.xml property files.
I tried with below application.yml properties but its not working.
spring.logging.level.org.apache.kafka:
clients.consumer.ConsumerConfig: INFO
clients.producer.ProducerConfig: INFO
common.utils.AppInfoParser: INFO
Try putting this in config file
<logger name="org.apache.zookeeper" level="OFF"/>
Similarly for kafka.

Log4j2 api cannot find Log4j2 core in OSGi environment

I'm trying to use log4j2 OSGi bundles, but it seems log4j2 api cannot find log4j2 core in an OSGi environment. I'm continuously getting the following exception :
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console
I found the same exception discussed in few places but still I could not figure out this issue. Isuspect I'm getting this issue because log4j2 api cannot find the log4j-provider.properties inside the META-INF directory of log4j2 core.
Is there any clue why I'm getting this exception and how can I correct the issue ?
(If anybody has correct pom file for adding log4j dependencies and bundling please share it with me)
These are the dependencies I have used
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.2</version>
</dependency>
I use apache felix as the bundle plugin. This error occures because resources inside the META-INF of log4j2-core specially the log4j-providoer.properties file is not visible to log4j api.
Thanks!
The log4j-core bundle registers a bundle listener when the Activator is started and starts searching for log plugins and if something is found it performs a sequence of operations similar to the usual Logger initialization (not really idiomatic OSGi stuff and i'm not sure it works, but it seems to set at least Log4jContextSelector and LoggerContextFactory), just to be sure of it, did you install and start the log4j-core bundle and verified that nothing changed?
Update:
I did some testing and found what is an acceptable solution/workaround for log4j2 OSGi issues. But as someone else recommended, alternatively i would use slf4j, pax-logging or simply the OSGi Log Service (the simpler of the bunch).
#Grant, you have 2 separate things that need to be fixed:
1. As you described, the "Log4j2 could not find a logging implementation" error is caused by the fact that the log4j2-api bundle is unable to find the log4j-provider.properties file and, after that is fixed, log4j2-api cannot find the log4j2-core classes (it's a different bundle and log4j2-api doesn't have a specific Import-Package: for those classes).
The workaround for this is to create a small fragment bundle for log4j2-api (i called mine log4j-api-config.jar) with that .properties file in META-INF and a manifest that forces a dynamic import:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Log4j API configurator
Bundle-SymbolicName: org.apache.logging.log4j.apiconf
Bundle-Version: 1.0.0
Bundle-Vendor: None
Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.2
Fragment-Host: org.apache.logging.log4j.api
DynamicImport-Package: *
I'm importing * here, you can improve it adding the required subset of log4j2-core packages that log4j2-api needs.
With this, that error will disappear, but log4j will notice that you didn't provide a log4j2 configuration file, next thing to fix (only if you care in this case).
2. At this point Felix will display this:
log4j2.xml not found by org.apache.logging.log4j.core
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
and i suppose you could want to add your own log4j2.xml without messing with the original log4j2-core.jar. You can do this creating another fragment bundle, this time hosted by log4j2-core, with just a log4j2.xml configuration file in the root and a simple manifest:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Log4j Core configurator
Bundle-SymbolicName: org.apache.logging.log4j.coreconf
Bundle-Version: 1.0.0
Bundle-Vendor: None
Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.2
Fragment-Host: org.apache.logging.log4j.core
I used this simple log4j2.xml configuration during my tests:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<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="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
With this you will not need that sort of "bridge" bundle you described below anymore, and you'll just need a simple Import-Package: org.apache.logging.log4j to use log4j from your bundle.
Update 2:
Important to note that the two fragments are NOT dependencies of the original bundles (no need to modify log4j jars or or even your bundles to add import/export), so the original bundles and your own custom ones will remain untouched.
Also, they don't depend on the original bundle either, they are just basic jar archive with a manifest and an additional text file, no code, no need for Import-Package or Export-Package.
You just need to install each fragment after their host bundle is installed.
I've created both fragments manually starting from an empty jar and copying inside the archive the properties file and modifying the MANIFEST.MF with a text editor, you can create them both with this pom.xml, remember to copy log4j-provider.properties where pom.xml is located.
For the log4j2-api fragment:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.group</groupId>
<artifactId>log4j2-api-config</artifactId>
<version>1.0</version>
<name>log4j2-api-config</name>
<packaging>bundle</packaging>
<properties>
<java-version>1.7</java-version>
</properties>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.0.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>org.apache.logging.log4j.apiconf</Bundle-SymbolicName>
<Bundle-Name>Log4j API Configurator</Bundle-Name>
<Bundle-Version>1.0.0</Bundle-Version>
<Fragment-Host>org.apache.logging.log4j.api</Fragment-Host>
<DynamicImport-Package>
*;resolution:=optional
</DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>.</directory>
<includes>
<include>log4j-provider.properties</include>
</includes>
<targetPath>META-INF</targetPath>
</resource>
</resources>
</build>
</project>
Modify this pom where appropriate(included file, bundle names) to generate the other one with the log4j2-core configuration.
Log4j is not suitable for an OSGi environment. Luckily there is a nice drop in replacement pax-logging. In your bundle you use the log4j api or any other of the supported apis (I prefer slf4j-api). Then you deploy pax logging to your OSGi framework and your bundle.
You can configure pax logging using a standard log4j config. So it is very easy to use. If you want a really easy start you can simply install apache karaf and deploy your bundle to it. Karaf already includes a fully set up pax logging.
Try changing the name of the jar file something does not contain core word (eg:log4j-zore) and try again
You need specify OSGI related dependencies on Your bundle in META-INF/MANIFEST.MF by add the following dependencies:
Require-Bundle: org.apache.logging.log4j.core;org.apache.logging.log4j.api
For me this error is resolved by:
ensuring that the log4j-api bundle is actually activated - and not just resolved - before calling the logger. I did this by setting it to Auto-Start with a low start level.
let log4j-api import classes of log4j-core (as mentioned by #uraime) to make sure it finds log4j-core. The cleanest way to do this is using a fragment. Instead of dynamic import you could also add this to the manifest:
Require-Bundle: org.apache.logging.log4j.core
I also use a fragment for log4j-core to let it find my log4j2.xml configuration file, but when not using this fragment, log4j will show a different error message.
Additionally I found that it's not required for the log4j-core bundle to be activated (only resolved) but note that this does mean that the Activator cannot find custom log4j2 plugins.

failing to load log4j2 while running fatjar

i am working on a project where i utilize log4j2 logging.
while developing in intellij, all works fine and the logging is done as expected. the log4j2.xml is linked through java property passed to jvm on startup via intellij settings.
but once i try to run a standalone gradle built fat-jar, i'm experiencing the following problems:
java -Dlog4j.debug=true -Dlog4j.configurationFile=/home/aaa/log4j2.xml -jar /home/aaa/myjar-SNAPSHOT.jar
exceptions:
ERROR StatusLogger Unrecognized format specifier [d]
ERROR StatusLogger Unrecognized conversion specifier [d] starting at position 16 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [thread]
ERROR StatusLogger Unrecognized conversion specifier [thread] starting at position 25 in conversion pattern.
...
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
i don't even understand where those [thread]s come from, since i get the same error even while using a basic simplest config in my log4j2:
<?xml version="1.0" encoding="UTF-8" ?><Configuration status="WARN" monitorInterval="86400">
<Appenders>
<Console name="console-log" target="SYSTEM_OUT">
<PatternLayout
pattern="%-5p %d{yyyy-MM-dd HH:mm:ss.SSS} ${hostName} %c{1} %msg %throwable{7}%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info" additivity="false">
<AppenderRef ref="console-log"/>
</Root>
</Loggers>
any thoughts are welcome. thanks.
in fatJar, dependencies can provide a log4j-provider.properties in the META-INF that cause this issue,
remove it in the gradle task :
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'project',
'Implementation-Version': project.version,
'Main-Class': 'com.sample.CLI'
}
baseName = project.name + '-all'
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it).matching {
exclude 'META-INF/**.RSA'
exclude 'META-INF/MANIFEST.MF'
exclude 'META-INF/log4j-provider.properties'
} } }
with jar
}
The problem is described here: https://issues.apache.org/jira/browse/LOG4J2-673
Unfortunately at the moment there only seems to be a solution for the maven-shade-plugin: https://github.com/edwgiz/maven-shaded-log4j-transformer
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.artifactId}${appSuffix}</finalName>
<transformers>
...
<transformer
implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer">
</transformer>
</transformers>
...
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.edwgiz</groupId>
<artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
Kinda late to this party, but I thought I'd add my situation, in case it helps anyone.
I build my own fat jar out of a subset of classes and jars from the larger project. The essential class runs, but I was getting all the "Unrecognized format specifier" and all. Most of the answers involve mvn shade or other such, so that wasn't helping me. But poking around, I learned that log4j-web.jar also includes the Log4jPlugins.dat file, causing the problems. Removing that from the build, and all is good.
(And I thought my build script was so tricky, including all the jars by project name, eg all jars for "log4j.")
The LoggerContextFactory binds the Log4j API to its implementation. The Log4j LogManager locates a LoggerContextFactory by locating all instances of META-INF/log4j-provider.properties, a standard java.util.Properties file, and then inspecting each to verify that it specifies a value for the Log4jAPIVersion property that conforms to the version required by the LogManager.
Incase of fat jar, you can also explicitly specify log4j2 to use LoggerContextFactory in your application by:
System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.core.impl.Log4jContextFactory")
or as specified in the log4j-provider.properties file included in your log4j-core jar.
When you run your application from an IDE, jar runs itself without embedding the dependencies and you don't have conflict of log settings. But when you convert the application into a fat jar then all the dependencies will be injected into your project's jar file and your log4j settings that come from external jar files (dependencies) may be conflicted while fatJar process merge them into a single artifact.
In this case i think your "Log4j2Plugins.dat" files may be conflicted. To be sure, you can open your fatJar file with a zip editor (ex: 7Zip), navigate to path in fatJar as below and delete one of the conflicted files (you can choose smallest one by size) from your fatJar. Run the fatJar and check the logging is working properly.
\META-INF\org\apache\logging\log4j\core\config\plugins\Log4j2Plugins.dat
Now we can check the dependencies (artifacts) and find which of them contain the "Log4j2Plugins.dat" files. So you can exclude the modules that have the file from your build tool and then your fatJar creation process will exclude the conflicted files and your new fatJar can start logging as expected.
In my case, my fatJar module imports some other modules from Spring Boot and when i exclude the conflicted logging libraries, my fatJar starts logging without any error.
configurations {
all*.exclude module: 'spring-boot'
all*.exclude module: 'spring-boot-starter-logging'
all*.exclude module: 'logback-classic'
all*.exclude module: 'commons-logging'
}

Using log4j on Google App Engine

I need to use log4j in my application, but I don't know how I can get properties loaded. Deafult properties files says that I should put log4j.properties to /WEB-INF/classes/ folder, but in eclipse I cannot see that folder and I cannot create it, because it already exists. And I cannot add any files to that folder either.
Here is error that I get:
log4j:WARN No appenders could be found for logger (DataNucleus.ClassLoading).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
So how can I get web application to load log4j properties?
Put the log4j.properties file into a source directory of your project, e.g. /src. Eclipse will copy it into your target build directory.
I recomend using SLF4J with Log4J, and the SpringSource Tool Suite (STS) for your project.
Here is how to get log4j working using Eclipse with the Google plugin.
Modify appengine-web.xml as follows:
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/classes/log4j.properties"/>
</system-properties>
You can add the following code to your servlet:
import org.apache.log4j.Logger;
...
Logger logger = Logger.getLogger("com.foo");
logger.debug("Yay2!");
Put the log4j.properties file in the src/ directory with the following content:
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{1}:%M:%L - %m%n
You can do a Project > Clean then allow it to automatically build, The build copies the log4j.properties file to /war/WEB-INF/classes/. You'll see the log displayed when you Run As > Web Application and request a URL.
I know that you're not using Maven but I will add instructions below in case anyone else needs them. These instructions will work with com.google.appengine.archetypes:guestbook-archetype.
Add the following to pom.xml:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
Add the following code to guestbook.jsp:
<%# page import="org.apache.log4j.Logger" %>
...
<%
Logger logger = Logger.getLogger("com.foo");
logger.debug("Yay2!");
%>
Create src/main/webapp/WEB-INF/classes/log4j.properties with the same content as above.
Then run:
mvn clean
mvn verify
mvn appengine:devserver
You will see log output in our console after calling http://localhost:8080/.
I have to put the log4j.properties and then configured in web.xml:
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
That way it runs before the classpath loading and it works.
Although it doesn't send the JUL stuff to log4j, so you will need a separated configuration to do that.
Ignore everything you see in the internet for the keywords spring + log4j + appengine.
The solution that worked for me and didn't created ambiguity was to leave JUL be and configure log4j with spring separately in this way:
public class CustomXmlWebApplicationContext extends XmlWebApplicationContext {
#Override
protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
super.initBeanDefinitionReader(beanDefinitionReader);
try {
Resource res = beanDefinitionReader.getResourceLoader().getResource("classpath:log4j.properties");
Properties props = new Properties();
props.load(res.getInputStream());
PropertyConfigurator.configure(props);
}
catch(Throwable e) {
e.printStackTrace();
}
}
}
Then just put your log4j.properties in the root of your source folder.
There is a good article on Logging in the Google AppEngine for Java (GAE/J) with Slf4j, Log4j and JUL.
In \src\main\webapp\WEB-INF\appengine-web.xml you need to have
appengine-web.xml
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/java-util-logging.properties"/>
</system-properties>
to tell GAE where java.util.logging (JUL) is configured.
In \src\main\webapp\WEB-INF\java-util-logging.properties you need
java-util-logging.properties
.level = ALL
or another of the JUL level names, as you like (i.e. 'TRACE' does not work).
In \src\main\resources\log4j.properties file you will have
log4j.properties
log4j.rootLogger=ALL, stdout
# or a lower log level such as DEBUG, INFO or WARN.
# Define the destination and format of our logging
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-5p: %m at %C.(%F:%L) on %d{ISO8601}%n
You need to add log4j to your CLASSPATH. I use Gradle for dependency management, so here is my build script:
build.gradle
configurations {
all*.exclude group: "commons-logging", module: "commons-logging"
}
dependencies {
// Logging
compile 'org.slf4j:slf4j-api:1.7.+'
runtime 'org.slf4j:slf4j-jdk14:1.7.+'
runtime ('log4j:log4j:1.2.17') {
exclude group: "com.sun.jdmk", module: "jmxtools"
exclude group: "com.sun.jmx", module: "jmxri"
exclude group: "javax.mail", module: "mail"
exclude group: "javax.jms", module: "jms"
}
}
If you are using Spring WebMVC, in order to provide a Log4J configuration file when starting up your application add the following listener to your Deployment descriptor.
web.xml
<!-- The definition of the Log4j Configuration -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>

Categories