I am running my Selenium Automation tests using Maven. From time of execution till end I see so many logs.
I came to know with this code that only .info warnings and .warn goes to console and .debug doesn't.
public static void main(String[] args) {
Logger log = LogManager.getLogger();
log.debug("its a debug message");
log.info("its a info message");
log.warn("its a warning message");
}
Output:
2015-12-24 13:58:21,166 ERROR Logger contains an invalid element or attribute "append"
[INFO ] 2015-12-24 13:58:21.245 [main] DebuggerTest - its a info message
[WARN ] 2015-12-24 13:58:21.247 [main] DebuggerTest - its a warning message
Now I want to pass on a variable in along with my mvn command that will switch on/off any logs in console.
Something like: mvn test --debugging -false So that logs can be seen in generated logs file but not in console.
More info:
I want something like given here:
How to initialize log4j properly?
here user "MATH" advised to use :
Logger.getRootLogger().setLevel(Level.WARN); if don't want to see debug logs
I want to enable/disable this from mvn command line.
More info 2:
this is how my log4j2.xml looks:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="log-path">logs</Property>
</Properties>
<Appenders>
<Console name="console-log" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
</Console>
<RollingFile name="trace-log" fileName="${log-path}/rnf-info.log"
filePattern="${log-path}/rnf-trace-%d{yyyy-MM-dd}.log" append="false">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
<RollingFile name="debug-log" fileName="${log-path}/rnf-debug.log"
filePattern="${log-path}/rnf-debug-%d{yyyy-MM-dd}.log" append="false">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.rnf" level="debug" additivity="false" append="false">
<appender-ref ref="trace-log" level="info"/>
<appender-ref ref="debug-log" level="debug"/>
</Logger>
<Root level="info" additivity="false">
<AppenderRef ref="console-log"/>
</Root>
</Loggers>
</Configuration>
I think you could use -Dlog4j.configuration=<path> to set the configuration of the logger to whatever you want directly on command line.
See documentation here: http://logging.apache.org/log4j/1.2/manual.html
What you can try to use are variables
log4j2 configuration
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="LEVEL">WARN</Property> <!-- default value -->
</Properties>
<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="${sys:LEVEL}">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
and to change the default value from WARN to DEBUG you can use
-DLEVEL=DEBUG
Edit:
In your configuration the level for console is fixed - static, set to INFO, but you want to have a dynamic behavior.
You need to add another property
<Properties>
<Property name="log-path">logs</Property>
<Property name="LEVEL">WARN</Property> <!-- default value -->
</Properties>
In which I set WARN as a default level, so by default, there will be less messages in console.
Then I'm referencing the property in Root logger configuration ${sys:LEVEL}
<Root level="${sys:LEVEL}">
but it can be specified from command line as standard JVM parameter -D....
So if you want more messages in console, you will run mvn test -DLEVEL=DEBUG
Related
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class AzulMain {
private static final Logger LOGGER = LogManager.getLogger(AzulMain.class.getName());
public static void main(String[] args){
LOGGER.info("Maybe my first Logger works?");
}
}
The imports work fine. I use these jar-files:
log4j-1.2-api-2.17.2.jar
log4j-api.2.17.2.jar
log4j-core-2.17.2.jar
And this is how my XML-file (log4j2.xml) looks. It is in the same folder as my AzulMain:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="log-path">log/${date:yyyy-MM-dd HH-mm-ss-SSS}</Property>
<Property name="archive">${log-path}/archive</Property>
</Properties>
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>
</PatternLayout>
</Console>
<File name="File-Appender-AzulMain" fileName="${log-path}/Azul.log">
<PatternLayout>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>
</PatternLayout>
</File>
<RollingFile name="RollingFile-Appender"
fileName="${log-path}/rollingfile.log"
filePattern="${archive}/rollingfile.log.%d{yyyy-MM-dd#HH-mm}.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="30 MB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="AzulMain" level="trace" additivity="false">
<AppenderRef ref="File-Appender-AzulMain" level="all"/>
<AppenderRef ref="Console-Appender" level="info"/>
</Logger>
<Root level="debug" additivity="false">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
</Configuration>
When I use JavaUtilLogger everything works quite fine so far, I can make it create a file and print to console, however, with log4j nothing works.
I tested deleting the XML file and adding BasicConfigurator.configure() into my main-method, but it still didn't work. If I start my main-method all I get is:
Process finished with exit code 0
What is strange to me is that when I use the command java -Dlog4j.debug -cp AzulMain, it does not show me my configuration as I would expect it, but just what seems to be a very generic help message.
It is my first time, I am using a logger. Does anyone know what the problem might be?
Update:
This helped me as a first step:
BasicConfigurator replacement in log4j2
I deleted the XML-file and used the new
Configurator.initialize(new DefaultConfiguration());
Configurator.setRootLevel(Level.INFO);
And now it works at least in so far as it prints to the console. However, I am still not able to make it use the log4j2.xml file. I tried naming it log4j2-test.xml, too. (Source) It did not make a difference.
Now it works. This is how I did it.
I set up a new project, with just a main-class and added a new xml-file with a file logger only at first, then added a logger to the console, too. I deleted cache in IntelliJ and deleted the Configurator-lines in the code.
This is the new XML-file log4j2.xml that made it work:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="basePath">log/${date:yyyy-MM-dd HH-mm-ss-SSS}</Property>
</Properties>
<!-- File Logger -->
<Appenders>
<!-- Console appender configuration -->
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>>
</PatternLayout>
</Console>
<RollingFile name="fileLogger"
fileName="${basePath}/Azul.log"
filePattern="${basePath}/app-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<!-- Max 10 files will be created everyday -->
<DefaultRolloverStrategy max="10">
<Delete basePath="${basePath}" maxDepth="10">
<!-- Delete all files older than 30 days -->
<IfLastModified age="30d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info" additivity="false">
<appender-ref ref="fileLogger" />
<appender-ref ref="Console-Appender" level="info"/>
</Root>
</Loggers>
</Configuration>
It seems to me to have been a mistake somewhere in the xml-file that I just couldn't figure out where it is.
My logging code:-
public void run(ApplicationArguments applicationArguments) throws Exception {
logger.debug("Debugging log");
logger.info("Info log");
logger.warn("Hey, Thi s is a warning!");
logger.error("Oops! We have an Error. OK");
logger.fatal("Damn! Fatal error. Please fix me.");
}
My log4j2.xml file:-
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<Properties>
<Property name="LOG_PATTERN">
%d{dd-MM-yyyy HH:mm:ss.SSS} %5p [%t] - (%F:%L) - %m%n
</Property>
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
<!-- Rolling File Appender -->
<RollingFile name="FileAppender" fileName="logs/currency_exchange.log"
filePattern="logs/currency_exchange-%d{dd-MM-yyyy}-%i.log">
<PatternLayout>
<Pattern>${LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<AsyncLogger name="com.example.log4j2demo" level="info"
additivity="info">
<AppenderRef ref="ConsoleAppender" />
<AppenderRef ref="FileAppender" />
</AsyncLogger>
<Root level="info">
<AppenderRef ref="ConsoleAppender" />
<AppenderRef ref="FileAppender" />
</Root>
</Loggers>
</Configuration>
As you can see the output in the console as:-
Also, the log entry is twice in the file. I want only one line of each log. The one with the link as this one:-
09-02-2020 10:36:02.280 INFO [main] -(Log4j2DemoApplication.java:21) - Info log
What is wrong? How to fix it?
You have given a wrong value in the additivity value of both loggers. Setting the additivity value to false will solve the messages duplication issue as it will prevent the logger from inheriting from its ancestor, in this case the root logger.
For the file name issue you mention in your comment: the filePattern property is used to generate the rolled log file name, that's the one on which you no longer write but keep for auditing/troubleshooting purposes, not the currently active one whose name is defined in the "fileName" tag instead.
I've made a war of my spring boot project that have the following structure.
base
+---logs
+---AuthorizationService
|
+----src -> main ---> java ---> com.project -> (classes)
|
+-> resources
|
+---->application.properties & log4j2.xml
+---ResourceService
|
+----src -> main ---> java ---> com.project -> (classes)
|
+-> resources
|
+---->application.properties & log4j2.xml
After the war build (as you can see the projects have due main modules)
I've uploaded it on a tomcat.
I've found the logfiles in the relative path specified , but when i do something on the app that normally trigger a log message, these files don't respond.
Here's the configuration via xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="60" status="WARN">
<Properties>
<Property name="logsRoot">${sys:catalina.home}/logs</Property>
</Properties>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
</Console>
<File name="LogFileAll" fileName="${logsRoot}/AuthorizationLogsAll.log" immediateFlush="true">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
</File>
<File name="LogFileError" fileName="${logsRoot}/AuthorizationLogsError.log" immediateFlush="true">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
</File>
<!--
<RollingFile name="LOGFILEALL" fileName="${logsRoot}/application.log" filePattern="${logsRoot}/application.log">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
<Policies>
<sizeBasedTriggeringPolicy size="10 MB" />
</Policies>
<DefaultRolloverStrategy min="1" max="4" />
</RollingFile>
-->
</Appenders>
<Loggers>
<Root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="LogFileAll"/>
</Root>
<logger name="com.pcsystem" level="info" additivity="true">
<appender-ref ref="LogFileError" level="warn"/>
<!-- ogni log message marcato con PCSYSTEM_CONSOLE sara' inserito nella console
<appender-ref ref="STDOUT">
<MarkerFilter marker="PCSYSTEM_CONSOLE" onMatch="NEUTRAL" onMismatch="DENY" />
</appender-ref>
-->
</logger>
<!-- opzioni per i loggers del contesto apache tomcat
<logger name="org.apache" level="info" additivity="true">
<appender-ref ref="LogFileAll" />
</logger>
-->
</Loggers>
I have 2 files of configuration 1 for module that target the same path.
Why my app doesn't speak?
Normal logs that in local environment never appear on the log file on "catalinahome"/logs
I've found the log file populated only with start message
EDIT
hey f1sh, you're showing me the light at the end of the tunnel, because the module structure seems to be different.
Actually launching pwd command on tomcat bash i've recovered this path:
home/intranet/tomcat/webapps/intrane-0.0.1/web-inf/classes
inside classe we have the xml but also application.properties. other files and the COM package that lead to
com.project.[...] classes
Is a configuration path problem?
Can Log4j2 be configured in such a way that the filters or some other components can filter out certain values from getting printed in the log? (but should allow other fields in the same line to pass through)
Say the following lines appear in the log
[operation=DONE, userName=junitUser, tenant=Tenant [tenantID=default], needDetails=1, message=BaseMsg [version=1.0, sdk=AppSDK [version=1.3, protocols=[4aac81ca, 393ae7a0]], device=Device [id=12345, type=Pompom, info=Dot's Device]]], channel=null
[operation=DONE, userName=junitUser224, tenant=Tenant [tenantID=default], needDetails=1, message=BaseMsg [version=1.0, sdk=AppSDK [version=1.3, protocols=[4aac81ca,393ae7a0]], device=Device [id=123456, type=Mamamia, info=tom's Device]]], channel=null
Now can I filter out the "userName" field in such a way that the log lines now do not contain it as shown below?
[operation=DONE, tenant=Tenant [tenantID=default], needDetails=1, message=BaseMsg [version=1.0, sdk=AppSDK [version=1.3, protocols=[4aac81ca, 393ae7a0]], device=Device [id=12345, type=Pompom, info=Dot's Device]]], channel=null
[operation=DONE, tenant=Tenant [tenantID=default], needDetails=1, message=BaseMsg [version=1.0, sdk=AppSDK [version=1.3, protocols=[4aac81ca,393ae7a0]], device=Device [id=123456, type=Mamamia, info=tom's Device]]], channel=null
Here is my 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>
<RollingFile name="RollingFile" fileName="/Users/dunston/logs/app.log"
filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
<RegexFilter regex=".* zinger_log .*" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<TimeBasedTriggeringPolicy />
</RollingFile>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
This can be accomplished with a RewriteAppender.
You may need to write a custom RewritePolicy that inspects the LogEvent's Message and replaces the Message with another instance if the formatted message contains a regular expression that you want to filter out.
Your custom RewitePolicy can be configured in the configuration like any other standard Log4j2 plugin.
I want to configure my log4j.xml with custom level of verbose - say 350 - in order to print up to some verbose level and including new prints of telemetry that will be at this new level - 350.
What is wrong/missing in my file?
<!--print logs of telemetry, warning and above -->
<CustomLevels>
<CustomLevel name="telemetryLevel" intLevel="350"/>
</CustomLevels>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="deviceTelemetry" fileName="/home/device/telemetry-${date:yyyy-MM-dd}.log" append="false"
filepattern="/home/device/telemetry-${date:yyyy-MM-dd}-%i.log">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10M"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="deviceTelemetry" level="telemetryLevel">
<AppenderRef ref="deviceTelemetry"/>
</Logger>
<Root>
<AppenderRef ref="Console" level="trace"/>
</Root>
</Loggers>
this way i get the logger in code:
Logger log = LogManager.getLogger("deviceTelemetry");
i don't know yet how to call the logger to append a message. there is a method log(Level level, String message) which gets a level so it might work - i cannot check it yet.