I try to use Windows 10 command line to print colored messages on console, but with no success. According to the Log4j 2 documentation, I should add the Jansi jar to my print application and set property log4j.skipJansi to false for enabling ANSI support on Windows. Could you, please, check and say what I did wrong:
Following code is my current work:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LoggerTest {
private static final Logger logger = LogManager.getLogger();
public static void main(String[] args) throws Exception {
logger.info("Hello!");
}
}
Following code is Log4j 2 configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="log4j.skipJansi" value="false"/>
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout>
<disableAnsi>false</disableAnsi>
<Pattern>%style{%d [%t] %c %p: %m}{yellow}%n%ex</Pattern>
</PatternLayout>
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
The contents of \lib directory:
log4j-core-2.12.1.jar
log4j-api-2.12.1.jar
jansi-1.18.jar
And the Windows compileAndRun.bat file:
#echo off
javac -cp lib\*;. LoggerTest.java
java -cp lib\*;. LoggerTest
pause
exit
However, the output in the command line is still not coloured. This is what I see:
So, the message contains ANSI escape codes, but they are not interpreted by command line. Though, if I try to copy/paste this output and echo it directly using another bat-file, then I see the coloured message.
It worked for when I add disableAnsi="false" propriety to <PatternLayout>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout
pattern="%highlight{%p} %logger{-2} - %m{FATAL=red blink,ERROR=red, WARN=yellow bold, INFO=green, DEBUG=green bold}%n" disableAnsi="false"/>
</Console>
</Appenders>
This is answer how to enable colors with latest log4j on windows 7:
openjdk 14
log4j 2.14.1
jansi 1.18
Configuration:
<?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] %highlight{%-5level}{FATAL=red blink, ERROR=red bold, WARN=yellow bold, INFO=magenta, DEBUG=green, TRACE=blue} %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
The key point is to pass -DLOG4J_SKIP_JANSI=false to JVM. Solution was found in this user guide.
Try executing this command: "reg add HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1"
In Java:
Runtime.getRuntime().exec("reg add HKCU\\Console /v VirtualTerminalLevel /t REG_DWORD /d 1");
I had to include both Jansi and Jcabi for cross-OS rendering -
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<version>1.18</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-log</artifactId>
<version>LATEST</version>
<optional>true</optional>
</dependency>
Related
java 1.8
maven 3.5
In pom.xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
In my Maven java project I want to generate new log file every new day (midnight).
So I use RollingFile and cron 0 0 0 * * ?. Here my log4j2.xml
<Properties>
<Property name="baseDir">logs</Property>
<Property name="patterLayout">%d{[dd.MM.yyyy HH:mm:ss.SSS]} %l %p:%n %m%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${patterLayout}"/>-
</Console>
<RollingFile name="RollingFile" fileName="${baseDir}/app.log"
filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="${patterLayout}"/>-
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy>
<Delete basePath="${baseDir}" maxDepth="2">
<IfFileName glob="*/app-*.log.gz"/>
<IfLastModified age="60d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
But all logs print in ONE file app.log.
Here result:
[27.11.2021 23:59:05.235] com.myproject.xls2metro2.App.main(App.java:18) TRACE:
JDK: 1.8.0_202
[27.11.2021 23:59:05.238] com.myproject.xls2metro2.App.main(App.java:33) WARN:
File path is mandatory
[28.11.2021 00:01:13.347] com.myproject.xls2metro2.App.main(App.java:18) TRACE:
JDK: 1.8.0_202
[28.11.2021 00:01:13.351] com.myproject.xls2metro2.App.main(App.java:33) WARN:
File path is mandatory
At first, verify that your original configuration doesn't have this hyphen character (probably you have added it accidentally while writing a question)
<PatternLayout pattern="${patterLayout}"/>-
Also, make sure that your code is wrapped inside the Configuration tag (I assume that you have omitted it for the sake of brevity):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
... your code here
</Configuration>
At second, your config looks exactly the same as in the official documentation examples, so it should be fine.
But in the documentation stated that:
The CronTriggeringPolicy triggers rollover based on a cron expression.
This policy is controlled by a timer and is asynchronous to processing
log events, so it is possible that log events from the previous or
next time period may appear at the beginning or end of the log file.
The filePattern attribute of the Appender should contain a timestamp
otherwise the target file will be overwritten on each rollover.
So probably, this is your case. Just wait a little longer to verify, that the next logs will be written to a separate file.
This question already has an answer here:
ParserConfigurationException while using log4j2 with junit
(1 answer)
Closed 10 months ago.
Switched from log4j1 to log4j2 (1.2.17 to 2.12).
I have 5 projects that use the new log4j2. I removed the old jar for log4j1, and all the references and paths now refer to the new added jar for log4j2.
I am using log4j2.xml to set the configuration for log4j2.
4 out of 5 other projects are running perfectly with the new log4j2, logging to the right file, with the correct pattern described in the log4j2.xml file.
One project - let's call it "ProjectX" - is returning an error when trying to access the same logger:
ERROR StatusLogger Caught javax.xml.parsers.ParserConfigurationException
The following are used when running the project:
jdk1.7.0_79
oracle.jdbc_11.1.1\ojdbc6dms.jar;
oracle.nlsrtl_11.1.0\orai18n.jar;
oracle.odl_11.1.1\ojdl.jar;
oracle.dms_11.1.1\dms.jar;
oracle.xdk_11.1.0\xmlparserv2.jar;
oracle.xdk_11.1.0\xml.jar;
com.oracle.toplink_1.0.0.0_11-1-1-5-0.jar;
org.eclipse.persistence_1.1.0.0_2-1.jar;
com.bea.core.antlr.runtime_2.7.7.jar;
javax.persistence_1.0.0.0_2-0-0.jar;
wlserver_10.3\server\lib\weblogic.jar;
commons-io-2.4.jar;
log4j-api-2.12.0.jar;
log4j-core-2.12.0.jar;
wlserver_10.3\server\lib\weblogic.jar
The log4j2.xml I'm using:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<!-- Path to the log files -->
<Property name="log-path">C:/logs</Property>
</Properties>
<Appenders>
<!-- Logger that prints to the Console window -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout>
<pattern>%-6p%d{DATE} - %C{1}.%M:%L - %m%n</pattern>
</PatternLayout>
</Console>
<!-- Logger that prints to the log file specified in the fileName -->
<RollingFile name="LoggerFile" fileName="${log-path}/App.log" filePattern="${log-path}/App-%d{yyyy-MM-dd}-%i.log" immediateFlush="true" append="true">
<PatternLayout>
<pattern>%-6p%d{DATE} - %C{1}.%M:%L - %m%n</pattern>
</PatternLayout>
<!-- The maximum size of a log file -->
<Policies>
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
<!-- Number of log files before starting to roll over -->
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="RollingFileLogger" level="DEBUG">
<AppenderRef ref="LoggerFile"/>
</Logger>
<Root level="DEBUG">
<AppenderRef ref="LoggerFile"/>
</Root>
</Loggers>
</Configuration>
Any idea what causes the error ERROR StatusLogger Caught javax.xml.parsers.ParserConfigurationException?
Could it be oracle.xdk_11.1.0\xmlparserv2.jar or xml.jar?
I tried xmlparserv2.jar version 12.2, and it fixed the error.
To download version 12.2 of xmpparserv2.jar:
https://maven.oracle.com/com/oracle/jdbc/xmlparserv2/12.2.0.1/xmlparserv2-12.2.0.1.jar
I upgraded the xmlparser jar from version 11.1 to version 12.2: xmlparserv2-12.2.0.1.jar.
I added it to the project and it fixed the problem.
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
I have a java application with log4j2 configured in order to log to console and to file.
When i start my application from ecplise, all the log are ok (console and file).
When i start the jar of the application from CMD or Powershell (as admin), only the console log works.
If i start the jar by only double click, the file log works (but no console is displayed).
This my log4j2.xml configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<File name="file_all" fileName="logs/ALL.log">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout>
</File>
<File name="file_error" fileName="logs/ERROR.log">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout>
</File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="file_all" level="INFO"/>
<AppenderRef ref="file_error" level="ERROR"/>
<AppenderRef ref="STDOUT" level="INFO"/>
</Root>
</Loggers>
</Configuration>
Your log4j2.xml config file starts with <configuration status="off" ... (or perhaps WARN or ERROR, you haven't shown the full config).
To investigate, switch on log4j's internal status logging by changing this to <configuration status="trace" ...
This will show output on the console. (You can redirect this to a file with java -jar myjar.jar > out.log.)
I hope this will give us more info on what is going on. Please paste that output into your question.
EDIT: the status output looks good; no errors or anything. Could it be that double-clicking a jar file is associated with javaw (not java), so there is no console? You mention that when starting the application from a CMD prompt or Powershell, you cannot find the log file. The line "Starting FileManager logs/ALL.log" in the status log tells me that log4j2 successfully created an output stream. However, this is a relative path, and the status log does not mention the absolute path. I think it is relative to the current directory, so what is the current directory of the CMD prompt or Powershell?
I am trying to to use Chainsaw to view my application's logger events but there is nothing showing up under the 'Zeroconf' tab in chansaw.
I've followed Scott's guide in log4j2 to chainsaw hello world not working… what am I doing wrong? - but no luck. I was going to comment on that question asking how teryet got it working in the end, but as my reputation is below 50, the site didn't allow me.
Environment
OS: OSX Mavericks
IDE: Netbeans 8.0 (Build 201403101706)
Java: 1.7.0_45; Java HotSpot(TM) 64-Bit Server VM 24.45-b08
log4j: 2.0rc1
Chainsaw: downloaded the latest DMG from http://people.apache.org/~sdeboy/
Things I've made sure
- included jmdns.jar in the classpath of my application
- Used PatternLayout in my config log4j.xml
- Ensure advertiser URL has three slashes
My log4j.xml config file
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF" advertiser="multicastdns">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%date{ABSOLUTE} [%thread] %logger{3}.%style{%method}{Blue}%style{(line%line)}{Red}%X %highlight{%-5level} - %msg%n%xEx"/>
</Console>
<RollingFile name="RollingFile" fileName="../logs/POS.log" filePattern="../logs/$${date:yyyy-MM}/POS-%d{yyyyMMdd-HHmmss}.log">
<PatternLayout pattern="%date{ABSOLUTE} [%thread] %logger{3}.%style{%method}{Blue}%style{(line%line)}{Red}%X %highlight{%-5level} - %msg%n%xEx"/>
<Policies>
<OnStartupTriggeringPolicy/>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
<File name="testFile" fileName="../logs/POS2.log" bufferedIO="false" advertiseURI="file:///localhost/Users/arthurhsieh/Documents/NetBeansProjects/AES/logs/POS2.log" advertise="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %m%n"/>
</File>
</appenders>
<loggers>
<root level="all"> <!-- <root level="trace"> -->
<appender-ref ref="Console"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="testFile" />
</root>
</loggers>
</configuration>
I can see logger events in the POS2.log file though.
Thanks in advance for any help/guidances. Cheers.
My issue went away after I restarted my system, i.e., Chainsaw is working and i can view my logs by connecting through the Zeroconf tab.
My guess is this is an Apple OS issue rather than Chainsaw itself.