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
}
Related
I am trying to send slf4j log messages in my Helidon MP application to a Kafka server that runs on port 9092. I have the following class as an example:
import lombok.extern.slf4j.Slf4j;
#Slf4j
public class Service {
private final ConfigProvider configProvider;
#Inject
public Service(ConfigProvider configProvider) {
this.configProvider = configProvider;
}
public String getString() {
String msg = String.format("%s %s !", configProvider.getString());
log.info("Entered getString() method");
return msg;
}
}
I also have a logging.xml file which specifies the Appender as KafkaAppender:
<Configuration>
<Appenders>
<Kafka name="KafkaAppender" topic="app-logs"
syncSend="false">
<Property name="bootstrap.servers"
value="localhost:9092"/>
</Kafka>
</Appenders>
<Loggers>
<Logger name="org.apache.kafka" level="WARN"/> <!-- avoid recursive logging -->
<Root level="INFO">
<AppenderRef ref="KafkaAppender"/>
</Root>
</Loggers>
</Configuration>
However, when I run the application, I get the following errors:
2022-11-28 14:23:17,358 main ERROR No layout provided for KafkaAppender
2022-11-28 14:23:17,362 main ERROR Null object returned for Kafka in Appenders.
2022-11-28 14:23:17,364 main ERROR Unable to locate appender "KafkaAppender" for logger config "root"
Any suggestions on how to make KafkaAppender work with Helidon?
Helidon does nothing special for logging. The only thing to note is that Helidon uses JUL (java.util.logging) for logging.
KafkaAppender is a Log4J2 appender, however you said "specify slf4j to send message to Kafka".
1. Setup the SLF4J to JUL bridge
See the javadocs.
Add the following dependency to your pom.xml:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
You can setup the bridge either programmatically or by configuration.
Programmatically
import org.slf4j.bridge.SLF4JBridgeHandler;
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
Using logging.properties
If you are using Helidon SE, you need to have code in your main class to load logging.properties. Helidon provides a utility for that, see below. If you are using Helidon MP, this is done for you automatically.
import io.helidon.common.LogConfig;
LogConfig.configureRuntime();
If you already have the statement above in your main method, you can setup the bridge by adding the following to your logging.properties file.
handlers = org.slf4j.bridge.SLF4JBridgeHandler
If you don't have a logging.properties file yet, create it under src/main/resources so that it is added to your project JAR.
2. Setup the SLF4J implementation
Import the Log4J2 bom in your pom.xml:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>2.19.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Add the following dependencies to your pom.xml:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
See the docs.
3. Configure Log4J2
See the docs.
The default path for a XML configuration file is log4j2.xml. Create the file at src/main/resources/log4j2.xml
<Configuration>
<Appenders>
<Kafka name="KafkaAppender" topic="app-logs" syncSend="false">
<PatternLayout pattern="%date %message" />
<Property name="bootstrap.servers" value="localhost:9092"/>
</Kafka>
</Appenders>
<Loggers>
<Logger name="org.apache.kafka" level="WARN"/> <!-- avoid recursive logging -->
<Root level="INFO">
<AppenderRef ref="KafkaAppender"/>
</Root>
</Loggers>
</Configuration>
Add the kafka-clients dependency to your pom.xml:
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</dependency>
Please note that there nothing specific to Helidon here apart from dependency version management and the utility provided to load logging.properties. You can use the same steps on any "plain" Java project.
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
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
I know there is allot of questions been asked on this but i have been trying to get this to work for few day's and i am not any more forward then when i started.
i have tried to use -Dlog4j.configuration=file:/path/to/log4j.properties and -Dlog4j.debug in eclipse vm arguments (under debug & run) and get no output
I have tried to use .properties and .xml but no joy
Tried to put the .xml and .properties files at the root, in the src and in an external folder which i added to my classpath ... still no joy
I think its using another .xml or .properties files in another lib/jar but because i cant get any debug to work i am finding very difficult to track what i am doing wrong here...
any help would be great! below is the code .. only the error message get's printed.
I have download (http://logging.apache.org/log4j/2.x/download.html) and imported into my app the
log4j-api-2.0-beta8.jar
log4j-core-2.0-beta8
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class CucmServMonitor
{
private static final Logger logger = LogManager.getLogger(CucmServMonitor.class.getName())
public static void main(String[] args)
{
logger.error("testing ERROR level");
logger.trace("exiting application");
System.out.println(logger.getName());
}
}
the xml file i am using just now log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration 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>
<root level="debug">
<appender-ref ref="Console"/>
</root>
</loggers>
</configuration>
Manage to figure this one out. The hint was here.
http://pic.dhe.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftasks-112.htm
I needed to add a "class folder" of where the log4j2.xml was located and then make sure it was at TOP of the list:
Right click on your project and go to properties
Then follow the step shown below. After adding the folder make sure its at the top and then click ok
Or... just create a resources directory like src/test/resources and add the log4j.xml file to that dir and then make that directory a source folder. Then eclipse will automatically copy the file to the the classes dir and there you have it.
1) Create the log4j.properties file inside the root folder
log4j.rootCategory=DEBUG, CONSOLE
# Appender writes to console
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
2) Modify the code like this
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class CucmServMonitor {
private static final Logger logger = Logger.getLogger(CucmServMonitor.class);
public static void main(String[] args) {
PropertyConfigurator.configure("log4j.properties");
logger.error("testing ERROR level");
logger.trace("exiting application");
System.out.println(logger.getName());
}
}
according to Alexis comment, I setup it, but eclipse still can not find log4j2.xml. finally, I solved it by removing the other jars imported, only keep log4j-api and log4j-core. before I imported all the jars downloaded from the Apache website. hope this can help someone.
According to Alexis comment, I setup it, but eclipse still can not find log4j2.xml. finally, I solved it by removing the other jars imported, only keep log4j-api and log4j-core. before I imported all the jars downloaded from the Apache website.
I solved my project for log4j->log4j2 version upgrading.
I've an issue with logback. I set it up (using maven) and everything seems fine except that Logback reports it can't find the configuration file (but I'm able to log to the console using the default logger configuration).
[#|2013-07-03T07:55:30.843+0200|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=124;_ThreadName=Thread-2;|07:54:39,844 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
07:54:39,844 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
07:54:39,844 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
07:54:39,847 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Setting up default configuration.
|#]
I put the configuration file (called logback.xml) into the src/main/resources folder of my Maven artifact (which is a WAR).
Interestingly, if I attempt to load the config from the classpath, I succeed:
Reader r = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("logback.xml"));
StringWriter sw = new StringWriter();
char[] buffer = new char[1024];
for (int n; (n = r.read(buffer)) != -1; )
sw.write(buffer, 0, n);
String str = sw.toString();
System.out.println(str);
Which prints my sample configuration file:
[#|2013-07-03T07:55:30.844+0200|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=124;_ThreadName=Thread-2;|<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{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root> </configuration>|#]
My pom.xml has the following entries:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
Which is packed as a WAR file (inside an EAR file). The location of the logback.xml inside the WAR file is as follows: WEB-INF/classes/logback.xml
Does anybody have an idea what's wrong with my setup?
Many thanks for your help
stupidSheep
The location within the WAR file is correct, WEB-INF/classes.
The logback configuration documentation talks about where the logback.xml file can be located within a war, but it doesn't mention anything about an EAR.
Could you please try the information at this link? I am wondering if it needs to be packed into the EAR in a specific way.
Glassfish 3 + ear + logback.xml
(edit: second link removed, didn't work)
Logback invokes very similar code to the code in your example, i.e.
getClassLoader().getResourceAsStream("logback.xml");
If logback cannot find logback.xml, then it must be that the resource is not visible to the class loader that loaded the logback class. This class loader is most probably different than the class loader that loaded your test code which can find logback.xml.
When you deliver the configuration file of the logging framework within an WAR works everything as expected and without any problems. But if you try this with an EAR something magically happens, the logging framework can’t find the configuration file. And it uses it’s default behavior.
I solved it doing the following:
Create a new folder directly under the EAR folder. For example, create
a new folder named "classes" --> MyEar/classes
Place your logback.xml file in this new folder:
MyEar/classes/logback.xml
In your WAR file's MANIFEST.MF file, add this new folder to the
classpath:
Manifest-Version: 1.0
Class-Path: classes
So I had similar problem where I had logback.xml in classpath but wasn't being included in the build process. I recently switched over to gradle. I was having issues initially with my resource files not included in the build even though I specifically added src/main/resources to sourceSet of build.gradle.
So my solution at the time was to put the types of files in the include:
includes = ["**/*.css", "**/*.wav", "**/*.mp3", "**/*.mp4", "**/*.png"]
Sometime passed and I noticed my logging config wasn't being applied. I spent a great deal of time tweaking the log and looking up the problem. I soon realized that the file wasn't being included.
String URL = "logback.xml";
System.out.println(ClassLoader.getSystemResource(URL));
I remembered I had to put the type of files in the include. I added the xml type and it worked.
sourceSets {
main {
resources {
srcDirs = ["src/main/java", "src/main/resources"]
includes = ["**/*.css", "**/*.wav", "**/*.mp3", "**/*.mp4", "**/*.png", "**/*.xml"]
}
}
}