Spring Boot and Logging with External Tomcat - java

I am deploying my Spring Boot Application on an external Tomcat Server. I can't seem to make my eclipse console display the log messages that I write in my code:
private static final Logger log = LoggerFactory.getLogger(PersonServiceImpl.class);
...
log.info("Running...");
I managed to log all hibernate trace but still can't show the log messages I am adding to my code:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
logging.level.root=INFO
logging.level.org.springframework.web=INFO
And the catalina log folder doesn't contain the logged infos I am needing.
What should I do?

I think, you deploy your spring boot application in an external tomcat, you package it as war file.
You can check this configuration :
In your pom.xml
<!-- mark the embedded tomcat server as provided -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
and in the packaging value :
<packaging>war</packaging>
In the dependencies, if you use the Web starter :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
it's depends transitively on the logging starter, that means we can only add the starter web dependecy, no more logging component to provide.
And In the application.properties file, add the following lines :
logging.level.org.springframework.web=INFO
logging.level.org.hibernate=INFO
After that, using maven, you can type :
mvn clean package
And move it to your external tomcat :
cp target/project.war apache-tomcat-8.X.X/webapps/project.war
./apache-tomcat-8.X.X/bin/startup.sh

Please configure your application.properties or application.yml
file
application.properties
#Logging pattern for file.
logging.pattern.file= "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
#output to a file
logging.file=/path_to_file/file_name.log
#Logging pattern for console and output.
logging.pattern.console= "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

Related

How to use log4j.xml for spring boot + log4j2 dependency

I have a log4j.xml with a customized appender like:
<appender name="console" class="com.example.MyAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m (%c{1}:%L)"/>
</layout>
</appender>
Recently I upgraded log4j dependency to log4j2, but still using this log4j.xml and it works.
Now, I add a Spring Boot module in my project. Following Spring doc, I set my pom.xml as
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.6.4</version>
</dependency>
And I also add arguments -Dlogging.config=log4j.xml -Dlog4j.configuration=log4j.xml -Dlog4j1.compatibility=true for it.
But my Spring application shows the error and no log output:
ERROR StatusLogger Unknown object "logger" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored: try nesting it inside one of: ["Appenders", "Loggers", "Properties", "Scripts", "CustomLevels"].
Seems log4j2 lib cannot recognize log4j.xml, which means -Dlog4j1.compatibility=true does not work for Spring Boot I think.
Any related config can be utilized or any workaround? Thanks.
TL;DR: The problem is that Log4j2 has two XML configuration factories (for the Log4j 1.x and Log4j 2.x formats), with the 2.x format having higher priority. You need to explicitly set the ConfigurationFactory to use:
-Dlog4j2.configurationFactory=org.apache.log4j.xml.XmlConfigurationFactory
When a Spring Boot application starts Log4j2 is configured twice:
at the very beginning using Log4j2 automatic configuration. For this round you just need to set -Dlog4j1.compatibility=true and call the config file log4j.xml or call the file differently and set -Dlog4j.configuration.
when Spring's environment is ready, Spring reconfigures Log4j2 programmatically using only a subset of Log4j2 automatic configuration. That is why this phase requires many manual settings:
-Dlogging.config=log4j.xml: Spring does not look for a file named log4j.xml,
-Dlog4j1.compatibility=true to activate the Log4j 1.x configuration factories,
-Dlog4j2.configurationFactory=org.apache.log4j.xml.XmlConfigurationFactory to increase the priority of the Log4j 1.x XML configuration factory.
Remark: Using a native Log4j 1.x custom appender exposes you to all the problems (synchronization and performance) of the original Log4j 1.x. For example Log4j 1.x looses events during reconfiguration (as the one performed by Spring Boot), whereas Log4j 2.x does not.

DailyRollingFileAppender not creating daily log file

DailyRollingFileAppender is not creating daily backup log file.
I am using the below config, which works on my local machine but it not working on the machine where my project has been deployed.
log4j.rootLogger=DEBUG, Appender2
log4j.appender.Appender2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Appender2.File=C:/Logs/AppLog.log
log4j.appender.Appender2.DatePattern='.'dd-MM-yyyy
log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender2.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
log4j.appender.Appender2.rootLogger = DEBUG
Framework - Spring MVC
I am not able to understand which part of the config is bloking DailyRollingFileAppender to create date wise log on my server machine.
Edit-
I updated my file as per the suggestion and it is not creating a new backup file at 12 am next day. means it updated AppLog.l‌​og till 12 then there was no backup file and all the previous day logs are gone and it starts writing from the beginning.
This is log4j properties now-
log4j.rootLogger=DEBUG, Appender2
log4j.appender.Appender2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Appender2.File=${catalina.home}/Logs/AppLog.log
log4j.appender.Appender2.DatePattern='.'yyyy-MM-dd
log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender2.Append=false
log4j.appender.Appender2.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
The issue is with the file path here:
log4j.appender.Appender2.File=C:/Logs/AppLog.log
Please make sure that this path exists on the server where you have deployed your project.
I faced with this problem before, the cause turned to be I used wrong log4j dependency in pom.xml. The previous dependency is:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
I use spring boot in my project, so I changed it to the following, it worked.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
your DatePattern should be '.'yyyy-MM-dd
refer to https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/DailyRollingFileAppender.html
u can use this for get the daily rolling log file,
########## Appender Daily Rolling
log4j.logger.appender=Daily
log4j.appender.Daily=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Daily.Threshold=INFO
log4j.appender.Daily.File=D:/backup/RFLI1010.log
log4j.appender.Daily.DatePattern='.'yyyy-MM-dd
# Append to the end of the file or overwrites the file at start.
log4j.appender.Daily.Append=true
log4j.appender.Daily.MaxBackupIndex=20
log4j.appender.Daily.layout=org.apache.log4j.PatternLayout
log4j.appender.Daily.layout.ConversionPattern= [%5p] %d %r %t (%F:%M:%L)%m%n%n

ERROR StatusLogger No log4j2 configuration file found. While updating the version 2.5.12 of Struts

As per the requirement and for security purpose I am updating Struts project. Before the Struts version is 2.3.24 and now I am updating it to 2.5.12. I have downloaded all the required jar files of Struts and applied to project but I am getting the below error
ERROR StatusLogger No log4j2 configuration file found. Using default
configuration: logging only errors to the console. Set system property
'org.apache.logging.log4j.simplelog.StatusLogger.level' to TRACE to
show Log4j2 internal initialization logging.
But I am not using any logger in my project. I have added all the dependency jar files and I am not using Maven, but added related libraries in lib folder. Any suggestions please.
Struts framework is using a logging framework log4j second version.
Struts 2.3 to 2.5 migration
Please be aware that the framework is using Log4j2 now as a main logging layer, the existing old logging layer is deprecated and will be removed soon. Log4j2 supports many different logging implementations, please check documentations for more details.
The file log4j2.xml is required to bootstrap the logging framework. But it's missing from the classpath. It's also missing from the Struts framework.
You should find some log4j2.xml, i.e. from the struts-showcase application or read a step 4 in this tutorial How To Create A Struts 2 Web Application
Step 4 - Add Logging
To see what’s happening under the hood, the example application for this tutorial uses log4j2. You’ll need to add a dependency node for log4j2 to the pom:
pom.xml log4j dependency node
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
Using both log4j-core and log4j-api allows to use the latest version of Log4j2 without a clash with version provided by the framework. Setup a log4j2.xml configuration in the src/main/resources folder which contains the following
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.opensymphony.xwork2" level="debug"/>
<Logger name="org.apache.struts2" level="debug"/>
<Root level="warn">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
Note the above log4j2 configuration specifies the console as the log target.
No log4j2 configuration file found means log4j2.xml configuration file is not in your classpath.
Check your project jar contains log4j confuguration file or not.
Otherwise you can set log4j confuguration file path as system property in your build script.
<sysproperty key="log4j.configurationFile" value="file:///${basedir}/src/log4j2.xml" />
Check https://logging.apache.org/log4j/2.x/manual/configuration.html for log4j configuration

How to make java.util.logging send logs to Logback?

I'm working on an app that logs using the slf4j api:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
private static final Logger LOG = LoggerFactory.getLogger(FreemarkerEmailPreviewGenerator.class);
...
LOG.error("Error generating email preview", e);
(Code above posted to show classes and packages in use, but pretty standard stuff.)
We use logback configured as follows:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{HH:mm:ss.SSS}] [%thread] [%-5level %logger{26} - %msg]%n
</pattern>
</encoder>
</appender>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
Some of our code makes use of 3rd party libraries that logs with java.util.logging - specifically freemarker. As you can see from the following console log entries, both logback and j.u.l are logging to the console, but they are not using the same config (the logback entries use our pattern, the j.u.l ones don't)
[12:24:38.842] [pool-2-thread-19] [INFO u.o.n.r.l.s.e.t.TemplateLoaderFromService - Finding template workflow/mail/templates/common/workflow-macros.ftl]
[12:24:38.859] [pool-2-thread-19] [INFO u.o.n.r.l.s.e.t.TemplateLoaderFromService - Loaded template workflow/mail/templates/common/workflow-macros.ftl as /workflow/mail/templates/common/workflow-macros.ftl from RegistryMailTemplateService.]
11-Jan-2017 12:24:38 freemarker.log.JDK14LoggerFactory$JDK14Logger error
SEVERE:
Expression domainContact is undefined on line 9, column 74 in workflow/mail/templates/common/workflow-macros.ftl.
The problematic instruction:
----------
==> ${domainContact.name} [on line 9, column 72 in workflow/mail/templates/common/workflow-macros.ftl]
Is it possible to make j.u.l logging use the logback config so that we have a single consistent logging config for the whole app?
Your application needs to have the following jars:
Application -> Freemarker -> java.util.logging -> SLF4J Api: jul-to-slf4j.jar
Application -> SLF4J API: slf4j-api.jar
SLF4J API -> logback: logback-classic.jar and logback-core.jar
Since your application already contains slf4j-api.jar and logback-classic.jar, you probably only have to add the jul-to-slf4j.jar
If you use maven:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.22</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.8</version>
</dependency>
logback classic will transitively add logback-core and slf4j-api

Log4j2 configuration - No log4j2 configuration file found

Lately I decided to learn how to use the log4j2 logger. I downloaded required jar files, created library, xml comfiguration file and tried to use it. Unfortunately i get this statement in console (Eclipse) :
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
This is my testing class code:
package log4j.test;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4jTest
{
static final Logger logger = LogManager.getLogger(Logger.class.getName());
public static void main(String[] args) {
logger.trace("trace");
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
logger.fatal("fatal");
}
}
And my xml config file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration package="log4j.test"
status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="log4j.test.Log4jTest" level="trace">
<AppenderRef ref="Console"/>
</Logger>
<Root level="trace">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
I tried also with xml without <Logger> tags, and package specification and in various folders/packages directories, but it didn't help. Now my log4j2.xml file is located directly in project folder in eclipse.
Is this a simple eclipse java project without maven etc? In that case you will need to put the log4j2.xml file under src folder in order to be able to find it on the classpath.
If you use maven put it under src/main/resources or src/test/resources
You need to choose one of the following solutions:
Put the log4j2.xml file in resource directory in your project so the log4j will locate files under class path.
Use system property -Dlog4j.configurationFile=file:/path/to/file/log4j2.xml
Was following the documentations - Apache Log4j2 Configuratoin and Apache Log4j2 Maven in configuring log4j2 with yaml. As per the documentation, the following maven dependencies are required:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.1</version>
</dependency>
and
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.8.6</version>
</dependency>
Just adding these didn't pick the configuration and always gave error. The way of debugging configuration by adding -Dorg.apache.logging.log4j.simplelog.StatusLogger.level=TRACE helped in seeing the logs. Later had to download the source using Maven and debugging helped in understanding the depended classes of log4j2. They are listed in org.apache.logging.log4j.core.config.yaml.YamlConfigurationFactory:
com.fasterxml.jackson.databind.ObjectMapper
com.fasterxml.jackson.databind.JsonNode
com.fasterxml.jackson.core.JsonParser
com.fasterxml.jackson.dataformat.yaml.YAMLFactory
Adding dependency mapping for jackson-dataformat-yaml will not have the first two classes. Hence, add the jackson-databind dependency to get yaml configuration working:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.6</version>
</dependency>
You may add the version by referring to the Test Dependencies section of log4j-api version item from MVN Repository. E.g. for 2.8.1 version of log4j-api, refer this link and locate the jackson-databind version.
Moreover, you can use the below Java code to check if the classes are available in the classpath:
System.out.println(ClassLoader.getSystemResource("log4j2.yml")); //Check if file is available in CP
ClassLoader cl = Thread.currentThread().getContextClassLoader(); //Code as in log4j2 API. Version: 2.8.1
String [] classes = {"com.fasterxml.jackson.databind.ObjectMapper",
"com.fasterxml.jackson.databind.JsonNode",
"com.fasterxml.jackson.core.JsonParser",
"com.fasterxml.jackson.dataformat.yaml.YAMLFactory"};
for(String className : classes) {
cl.loadClass(className);
}
Eclipse will never see a file until you force a refresh of the IDE. Its a feature! So you can put the file all over the project and Eclipse will ignore it completely and throw these errors. Hit refresh in Eclipse project view and then it works.
Additionally to what Tomasz W wrote, by starting your application you could use settings:
-Dorg.apache.logging.log4j.simplelog.StatusLogger.level=TRACE
to get most of configuration problems.
For details see Log4j2 FAQ: How do I debug my configuration?
In my case I had to put it in the bin folder of my project even the fact that my classpath is set to the src folder. I have no idea why, but it's worth a try.
log4j-test.xml => name of the configuration file if placed in /test/resources
#TestPropertySource(properties = {
"log4j.configurationFile","log4j-test.xml"
})
#CucumberContextConfiguration
#ContextConfiguration(classes = TestConfiguration.class)
public class Steps{
private Logger log = LogManager.getLogger(Steps.class);
//implementation
}

Categories

Resources