I cannot get Log4j 2 to log to the console. Nothing is showing up when running with gradle.
log4j2.xml in the projects root directory:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="ALL">
<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="all">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Usage in my classes:
public class ABCHandler {
private final Logger logger = LogManager.getLogger();
public ABC(String serialPortName) {
logger.info("Opening serial port {}", serialPortName);
}
}
Loading your file and configurations on my machine works.
This was the class I used:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Test
{
private final Logger logger = LogManager.getLogger(Test.class);
public Test(String serialPortName) {
System.out.println(logger.isInfoEnabled());
logger.entry();
logger.info("info! {}", serialPortName);
logger.error("error! {}", serialPortName);
logger.debug("debug! {}", serialPortName);
}
public static void main(String args[])
{
Test h1 = new Test("1001");
}
}
This is the log4j2.xml:
<ThresholdFilter level="all"/>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p method: [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="all">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
and finally, this is the output:
true
2014-05-29 12:19:15,266 TRACE method: [main] Test (Test.java:10) - entry
2014-05-29 12:19:15,268 INFO method: [main] Test (Test.java:11) - info! 1001
2014-05-29 12:19:15,269 ERROR method: [main] Test (Test.java:12) - error! 1001
2014-05-29 12:19:15,269 DEBUG method: [main] Test (Test.java:13) - debug! 1001
One common error when using Log4j2 is placing the log4j2.xml in a file that is not in the classpath.
To diagnose if that is the problem, change the line
logger.info("Opening serial port {}", serialPortName);
to
logger.error("Opening serial port {}", serialPortName);
If you see any output it is because log4j can't load your file. This is because the default log level when the file is not found is ERROR, not DEBUG.
The location of the log4j2.xml on my project (Maven) is in src/main/resources, which I know it is in my classpath.
My problems were:
I was using a log4j.properties file. Once renamed to log4j2.properties the main and test classpaths picked it up
I had to add logging to standard output to build.gradle
test {
testLogging.showStandardStreams = true
}
note: when I added sourcesets according to here it still didn't find the log4j.properties file only renaming it worked!
Related
I have created the below basic program in JAVA to display the log message in console using log4j,
import org.apache.logging.log4j.*;
import org.apache.logging.*;
public class Test {
public final static Logger log=LogManager.getLogger(Test.class.getName());
public static void main(String[] args) {
log.log(Level.TRACE,"Testing");
if(log.isTraceEnabled())
System.out.println("Trace Enabled");
else
System.out.println("Trace not Enabled");
log.trace("Entering Log4j Example.");
log.info("Started");
log.fatal("Error occured");
log.error("Dkjdsfh");
log.debug("Debugging");
log.info("Success");
log.warn("Warning");
}
}
But, the above code displaying only ERROR/FATAL message, other log messages not displayed in console. Below is my log4j.xml configuration,
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<!-- Define custom levels before using them for filtering below. -->
<CustomLevels>
<CustomLevel name="DIAG" intLevel="350" />
<CustomLevel name="NOTICE" intLevel="450" />
<CustomLevel name="VERBOSE" intLevel="550" />
</CustomLevels>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
</Console>
<File name="MyFile" fileName="logs/app.log">
<PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="trace">
<!-- Only events at DIAG level or more specific are sent to the console. -->
<AppenderRef ref="Console" level="diag" />
<AppenderRef ref="MyFile" level="trace" />
</Root>
</Loggers>
</Configuration>
Also, I have the below jar files to the build path,
log4j-api-2.13.3.jar
log4j-core-2.13.3.
Output of my program:
Trace not Enabled
16:55:40.104 [main] FATAL Test - Error occured
16:55:40.107 [main] ERROR Test - Dkjdsfh
Can someone please help me where I am doing mistake?
Thanks in advance.
You set your custom "DIAG" level to 350. 350 is lower than INFO (400), so INFO, DEBUG and TRACE levels are not shown on the console.
If you check your file output, it should contain everything.
OFF 0
FATAL 100
ERROR 200
WARN 300
INFO 400
DEBUG 500
TRACE 600
Either change the intLevel or pass a different level to the appender.
See custom log levels
I have the followed imports:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
and the following instantiation:
private static Logger logger = LoggerFactory.getLogger(Test.class);
and the following in my Main method:
logger.info("SOME MESSAGE: ");
However, I'm not able to find the output anywhere. All I see is that in my console there is:
21:21:24.235 [main] INFO some_folder.Test - SOME MESSAGE:
How do I locate the log file?
Note that the following are on my build path:
slf4j-api-1.7.5.jar
slf4j-log4j12-1.6.4.jar
I read the answer to similar questions but nobody actually says how to fix the problem.
slf4j is only an API. You should have a concrete implementation (for example log4j). This concrete implementation has a config file which tells you where to store the logs.
When slf4j catches a log messages with a logger, it is given to an appender which decides what to do with the message. By default, the ConsoleAppender displays the message in the console.
The default configuration file is :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<!-- By default => console -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
If you put a configuration file available in the classpath, then your concrete implementation (in your case, log4j) will find and use it. See Log4J documentation.
Example of file appender :
<Appenders>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
...
</Appenders>
Complete example with a file appender :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
As already mentioned its just a facade and it helps to switch between different logger implementation easily. For example if you want to use log4j implementation.
A sample code would looks like below.
If you use maven get the dependencies
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
Have the below in log4j.properties in location src/main/resources/log4j.properties
log4j.rootLogger=DEBUG, STDOUT, file
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=mylogs.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{dd-MM-yyyy HH:mm:ss} %-5p %c{1}:%L - %m%n
Hello world code below would prints in console and to a log file as per above configuration.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
It does not write to a file by default. You would need to configure something like the RollingFileAppender and have the root logger write to it (possibly in addition to the default ConsoleAppender).
The log file is not visible because the slf4j configuration file location needs to passed to the java run command using the following arguments .(e.g.)
-Dlogging.config={file_location}\log4j2.xml
or this:
-Dlog4j.configurationFile={file_location}\log4j2.xml
Log4j is finding my config, because as soon as I delete it I get an error message saying it couldn't find one, however it's properties are not reflected when logging.
log4j2.properties:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="TRACE">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Test.java:
public class Test {
private static Logger logger = LogManager.getLogger(Test.class);
public static void main(String[] args) throws Exception {
logger.info("test");
logger.fatal(logger.getLevel());
}
}
Output:
20:19:31.848 [main] FATAL io.rj93.sarcasm.examples.CnnSentenceClassificationExample - ERROR
As you can see, the logger is returning the level to be ERROR when it is set to INFO, and the time format is including the milliseconds even though it has been removed.
The config file is taken from the log4j website, with only minor changes (the two mentioned, and status="TRACE")
I am using version 2.8.1.
You use a log4j2.properties file with a XML configuration inside it.
It is not consistent.
The log4J initialization doesn't recognize the format used as a properties format. So it uses the default log4J configuration that specifies ERROR level for the root logger.
Simply rename log4j2.properties to log4j2.xml and it should be fine.
I'm trying to use the new log4j2 with a Socket Appender but I'm a bit unlucky.
Here is my XML configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<Socket name="socket" host="localhost" port="9600">
<SerializedLayout />
</Socket>
</Appenders>
<Loggers>
<Logger name="com.mycorp" level="info" />
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="socket"/>
</Root>
</Loggers>
</Configuration>
Here is my Java code:
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.io.*;
import java.sql.SQLException;
import org.apache.logging.log4j.core.net.*;
public class SyslogLogger
{
private static final Logger LOG = LogManager.getLogger(SyslogLogger.class);
public static void main (String[] args)throws IOException,SQLException
{
LOG.info("commit(). Query {}", "commit(). Query {}");
}
}
When executing the code I'm getting:
2016-06-29 17:13:42,426 main ERROR Unable to write to stream TCP:127.0.0.1:9600 for appender socket: org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:127.0.0.1:9600 socket not available
2016-06-29 17:13:42,426 main ERROR An exception occurred processing Appender socket org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:127.0.0.1:9600 socket not available
Should I create a TCP socket explicitly? or Log4j2 does it for me?
I saw a few posts about Logstash, is that required here?
Please note that I just want to sent the messages, without actually catching them at this time.
In addition, I'm experiencing similiar issues with Syslog Adapter as well.
You need a server side to this client which logs the events to socket appender.
Your server side would look something like :
public static void main(String args[])
{
TcpSocketServer server = null;
try {
server = new TcpSocketServer(9600,new ObjectInputStreamLogEventBridge());
}
catch (IOException e)
{
e.printStackTrace();
}
server.run();
}
Here, a Tcp Socket is open on 9600 and keeps listening for log events as long as this server runs.
You would also need a log4j2 configuration corresponding to this server.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyAppServer" packages="">
<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="com.mycorp" level="info" />
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Now, all the log events written by any logger which is a child to com.mycorp would be appended to console where your server runs.
Hope it helps.
I am trying to use log4j2 with disruptor in a java application. I have the following jar files in my classpath:
log4j-api-2.0-rc2.jar
log4j-core-2.0-rc2.jar
disruptor-3.2.0.jar
In my Java class, I a doing the following to test:
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class LoggerTest {
private static final Logger Logger = LogManager.getLogger(LoggerTest.class.getName());
public static void main(String[] args) {
Logger.info("testing log4j2 with disruptor");
}
My log4j2.xml file is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Don't forget to set system property
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
to make all loggers asynchronous. -->
<configuration status="INFO">
<appenders>
<!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
<FastFile name="RandomAccessFile" fileName="logs/test.log" immediateFlush="false" append="false">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m %ex%n</pattern>
</PatternLayout>
</FastFile>
</appenders>
<loggers>
<root level="info" includeLocation="true">
<appender-ref ref="RandomAccessFile"/>
</root>
</loggers>
</configuration>
When I run the application, I get the following error (with no log output):
2014-07-10 14:45:32,930 ERROR Error processing element FastFile: CLASS_NOT_FOUND
2014-07-10 14:45:32,973 ERROR Unable to locate appender RandomAccessFile for logger
In beta9, the <FastFile> appender was renamed to <RandomAccessFile>. If you rename this element in your configuration it should work.