I want my app to have 4 log files. Three of the log files are the typical log4j Info, Warn and Error logs. The 4th log file is completely unrelated and is used to log some data.
My log4j.properties file looks like this:
log4j.threshold=ALL
log4j.rootLogger=ALL, InfoAppender, WarnAppender, ErrorAppender
log4j.DATA_LOGGER=INFO, DataAppender
log4j.additivity.DATA_LOGGER = false
log4j.appender.DataAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DataAppender.File=/app_logs/data.log
log4j.appender.InfoAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.InfoAppender.File=/app_logs/info.log
log4j.appender.WarnAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.WarnAppender.File=/app_logs/warn.log
log4j.appender.ErrorAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ErrorAppender.File=/app_logs/error.log
And my Java code looks like this:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private static final Log LOG = LogFactory.getLog(SomeClassInMyApp.class);
private static final Log DATA_LOG = LogFactory.getLog("DATA_LOGGER");
private static void foo() {
LOG.info("Hello");
DATA_LOG.info("Some data");
}
When I run this, the "Hello" text is correctly written to the info.log file. But the data.log file is never created or written to.
Why is the DATA_LOG.info("Some data") line not writing to the data.log file, and what code change do I need to make in order for that to happen?
commons should work as well, can you try this
import org.apache.log4j.Logger;
...
...
Logger log = Logger.getLogger("DATA_LOGGER");
...
...
log.info("my data");
instead of this
import org.apache.commons.logging.Log;
Update Just tested this code works:
log4j.properties
log4j.rootLogger = DEBUG, R
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=E:/testroot.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{DATE} %-5p %c:%L %x - %m%n
##########################################################################
################## Appender for Other Logger ############################
##########################################################################
log4j.logger.TestLog=DEBUG, cache
log4j.additivity.TestLog=false
log4j.appender.cache=org.apache.log4j.DailyRollingFileAppender
log4j.appender.cache.File=E:/testcache.log
log4j.appender.cache.layout=org.apache.log4j.PatternLayout
log4j.appender.cache.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %c %m%n
Test Code
private static final Logger DATA_LOG = Logger.getLogger("TestLog");
private static final Logger LOG = Logger.getLogger(Test.class);
public static final void main(String[] args){
LOG.error("MSG1");
DATA_LOG.error("MSG2");
}
Output
testroot.log
09 Feb 2011 12:18:29,671 ERROR in.naishe.so.Test:11 - MSG1
testcache.log
09/02/2011 12:18:29 TestLog MSG2
Are you missing something?
Related
I am facing an issue with configuring log4j2 logs programmatically.
Please see the below code, I am creating 2 objects of the class App3, and I want to create 2 debug log files(a log file per App3 object), thereafter each object should be able to log to corresponding log file.
But my code is logging all the logs to the second log file after 2nd log is created. Can someone help on this.
Output of the program
file Name: app3_logger1.log_debug.log
2020-06-16 16:19:31,100 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1
file Name: app3_logger2.log_debug.log
2020-06-16 16:19:31,211 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2
2020-06-16 16:19:31,216 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2
2020-06-16 16:19:31,216 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1
2020-06-16 16:19:31,216 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1
2020-06-16 16:19:31,217 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2
Java Class - you just need to add log4j2 dependencies to compile
public class App3 {
public Logger logger;
public static void main(String[] args) {
App3 app1 = new App3();
app1.initializeYourLogger("app3_logger1.log", "%d %p %c [%t] %m%n");
app1.testProg("app3_logger1");
App3 app2 = new App3();
app2.initializeYourLogger("app3_logger2.log", "%d %p %c [%t] %m%n");
app2.testProg("app3_logger2");
app2.testProg("app3_logger2");
app1.testProg("app3_logger1");
app1.testProg("app3_logger1");
app2.testProg("app3_logger2");
}
public void testProg(String s) {
logger.debug("Hello from Log4j 2" + s);
}
public void initializeYourLogger(String fileName, String pattern) {
this.logger = LogManager.getLogger(fileName);
ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setStatusLevel(Level.DEBUG);
builder.setConfigurationName(fileName);
AppenderComponentBuilder componentBuilder = builder.newAppender("log", "File");
componentBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", pattern));
RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);
LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout").addAttribute("pattern", pattern);
ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
.addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "10MB"));
componentBuilder = builder.newAppender("LogToRollingErrorFile", "RollingFile")
.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY)
.addAttribute("level", Level.ERROR))
.addAttribute("fileName", fileName + "_error.log")
.addAttribute("filePattern", fileName + "-%d{MM-dd-yy-HH-mm-ss}_error.log").add(layoutBuilder)
.addComponent(triggeringPolicy);
builder.add(componentBuilder);
componentBuilder = builder.newAppender("LogToRollingDebugFile", "RollingFile")
.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY)
.addAttribute("level", Level.DEBUG))
.addAttribute("fileName", fileName + "_debug.log")
.addAttribute("filePattern", fileName + "-%d{MM-dd-yy-HH-mm-ss}_debug.log").add(layoutBuilder)
.addComponent(triggeringPolicy);
builder.add(componentBuilder);
AppenderRefComponentBuilder rollingError = rootLogger.getBuilder().newAppenderRef("LogToRollingErrorFile");
AppenderRefComponentBuilder rollingDebug = rootLogger.getBuilder().newAppenderRef("LogToRollingDebugFile");
rootLogger.add(rollingError);
rootLogger.add(rollingDebug);
builder.add(rootLogger);
Configurator.reconfigure(builder.build());
}
}
This is exactly what I want to do in log4j older version, I am still struggling with log4j2,
private void initLogger(String serviceName, String instance) throws IOException {
String loggerName = serviceName+"_"+instance;
this.logger = Logger.getLogger(loggerName);
this.logger.removeAllAppenders();
PatternLayout layout = new PatternLayout();
layout.setConversionPattern("%d: %m%n");
String loggingFolder = this.properties.getLoggingFolder();
String debugFileName = loggingFolder+"/"+loggerName+"_debug.log";
String errorFileName = loggingFolder+"/"+loggerName+"_error.log";
RollingFileAppender debugAppender = new RollingFileAppender(layout, debugFileName, true);
debugAppender.setThreshold(Level.DEBUG);
debugAppender.setMaxFileSize("10000000");
debugAppender.setMaxBackupIndex(49);
logger.addAppender(debugAppender);
RollingFileAppender errorAppender = new RollingFileAppender(layout, errorFileName, true);
errorAppender.setThreshold(Level.ERROR);
errorAppender.setMaxFileSize("10000000");
errorAppender.setMaxBackupIndex(49);
logger.addAppender(debugAppender);
}
Actually, I am quite sure your Logger is being updated correctly. The problem is that both application instances are going to use the same Logging configuration.
If you look at Log4j's architecture you will see that the Loggers and the configuration are anchored in the LoggerContext. By default, Log4j uses the ClassLoaderContextSelector, which means that every ClassLoader can have its own LoggerContext. Your sample application only has a single ClassLoader and so will only have a single LoggerContext and, therefore, only a single Configuration.
So when you reconfigured the second time you simply replaced the prior configuration with the new one. Since the root logger is handling all log events it will route the events from both Loggers you have created to the file created in the second configuration.
If you want logs to end up in two different files then create a configuration with both files and figure out a way to route them to the correct file, either via logger names or filters.
As per observation, your logger is updated with the last initialization so after app2.initializeYourLogger() your object-level logger object updated with App2 configuration.
You need to return the logger object from initializeYourLogger() and also create separate Logger object.
If I put info, only error log is printed.
If I put debug, only error log is printed.
Why is the logging level not working?
public class Test {
private static Logger log = Logger.getLogger(Test.class);
public static void main(String[] args) {
// TODO Auto-generated method stub
BasicConfigurator.configure();
log.info("info test");
log.debug("debug test");
log.error("error test");
}
}
Console:
0 [main] ERROR com.testfiles.Test - error test
log4j properties file:
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, theConsoleAppender
# A1 is set to be a ConsoleAppender.
log4j.appender.theConsoleAppender=org.apache.log4j.ConsoleAppender
# A1 uses PatternLayout.
log4j.appender.theConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.theConsoleAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
You're not supposed to call the BasicConfigurator directly if you have a properties file. Remove that call and the properties file should be picked up, provided it's on the classpath.
i am using multiple loggers to append into multiple log files.the path of these log files are set dynamically.
i am doing my project in java and using log4j framework.
my project structure.
src
log4test
log4test.java
log4test2
log4test2.java
log4j.properties
log4test.java:-
public class Log4Test{
public static void main(String[] args)throws IOException,SQLException{
System.setProperty("logs", "C:\\New folder 3\\logs.log");
Logger log = Logger.getLogger("file");
log.info("hello");
Log4Test2.fefe();
}
}
log4test2.java:-
public class Log4Test2{
/* Get actual class name to be printed on */
public static void fefe()throws IOException,SQLException{
System.setProperty("logs.file", "C:\\New folder 2\\logs.log");
Logger log = Logger.getLogger("admin");
log.info("Debug2");
log.info("Info2");
}
}
log4j.properties:-
log4j.rootLogger=INFO
log4j.logger.file=INFO, file
log4j.logger.admin=INFO, admin
# Define the file appender
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=$[logs}
# Define the layout for file appender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss}
[%p] %m%n
# Define the file appender
log4j.appender.admin=org.apache.log4j.FileAppender
log4j.appender.admin.File=${logs.file}
# Define the layout for file appender
log4j.appender.admin.layout=org.apache.log4j.PatternLayout
log4j.appender.admin.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss}
[%p] %m%n
i am getting this error:-
log4j:ERROR setFile(null,true) call failed
Could you check this line
# Define the file appender
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=$[logs} //TODO should be ${logs}
If I am not mistaken. Thank you.
The second thought is:
public class Log4Test2{
private final Logger logger = LoggerFactory.getLogger("admin");
public void fefe()throws IOException,SQLException{ //try remove static
System.setProperty("logs.file", "C:\\New folder 2\\logs.log");
log.info("Debug2");
log.info("Info2");
}
How to save the logs in text file which gets generated in selenium webdriver?
I know how to log normal logs in java like using logger.
Below is the step which i tried to log.
Logger logger = Logger.getRootLogger();
PropertyConfigurator.configure("data/config/log4j.properties");
FileAppender appender = (FileAppender)logger.getAppender("file");
String logFilePath ="C:\\Users\\priyarsi\\Desktop\\LdapLog.txt";
appender.setFile(logFilePath);
appender.setThreshold(Level.DEBUG);
appender.setAppend(true);
appender.activateOptions();
log.debug("Hello this is an debug message");
log.info("Hello this is an info message");
Can anyone please help me in logging selenium webdriver output to a text file?
Try this out -
# Root logger option
log4j.rootLogger=INFO, file, stdout
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=../AutoLogs.log
#log4j.appender.file.File=${file.name}
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} %5p %c{1}:%L %t - %m%n
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} %5p %c{1}:%L %t - %m%n
You can try logging Log4j API. It is very easy to understand and implement. Perform following steps:
Download Log4j jars from (https://logging.apache.org/log4j/1.2/download.html)
Add downloaded jars to project's build path.
Create a new XML file – log4j.xml and place it under the Project root folder.
Add new xml file or you can customise it the way you want. (http://toolsqa.com/selenium-webdriver/log4j-logging/)
Create new Java Class and paste following code:
package utility;
import org.apache.log4j.Logger;
public class Log {
// Initialize Log4j logs
private static Logger Log = Logger.getLogger(Log.class.getName());//
// This is to print log for the beginning of the test case, as we usually
// run so many test cases as a test suite
public static void startTestCase(String sTestCaseName) {
Log.info("****************************************************************************************");
Log.info("****************************************************************************************");
Log.info("$$$$$$$$$$$$$$$$$$$$$ " + sTestCaseName + " $$$$$$$$$$$$$$$$$$$$$$$$$");
Log.info("****************************************************************************************");
Log.info("****************************************************************************************");
}
// This is to print log for the ending of the test case
public static void endTestCase(String sTestCaseName) {
Log.info("XXXXXXXXXXXXXXXXXXXXXXX " + "-E---N---D-" + " XXXXXXXXXXXXXXXXXXXXXX");
Log.info("X");
Log.info("X");
Log.info("X");
Log.info("X");
}
// Need to create these methods, so that they can be called
public static void info(String message) {
Log.info(message);
}
public static void warn(String message) {
Log.warn(message);
}
public static void error(String message) {
Log.error(message);
}
public static void fatal(String message) {
Log.fatal(message);
}
public static void debug(String message) {
Log.debug(message);
}
}
Call above methods in your test scripts.
I can't figure out how to configure my log4j so that my debugLog and my reportsLog are separate from each other (not additive). Why is it, that in the configuration below, the reportsLog is always empty?
log4j.rootLogger=TRACE, stdout, debugLog
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.appender.debugLog=org.apache.log4j.FileAppender
log4j.appender.debugLog.File=logs/debug.log
log4j.appender.debugLog.layout=org.apache.log4j.PatternLayout
log4j.appender.debugLog.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.reportsLog=DEBUG,reportsLog
log4j.appender.reportsLog=org.apache.log4j.FileAppender
log4j.appender.reportsLog.File=logs/reports.log
log4j.appender.reportsLog.layout=org.apache.log4j.PatternLayout
log4j.appender.reportsLog.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
And here is my Java code:
package test;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class HelloLogger {
static final Logger debugLog = Logger.getLogger("debugLog");
static final Logger resultLog = Logger.getLogger("reportsLog");
public static void main(String[] args) {
PropertyConfigurator.configure("log4j.properties");
debugLog.debug("Hello debugLog message");
resultLog.debug("Hello reportsLog message");
}
}
Try the following configuration:
log4j.rootLogger=TRACE, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.appender.debugLog=org.apache.log4j.FileAppender
log4j.appender.debugLog.File=logs/debug.log
log4j.appender.debugLog.layout=org.apache.log4j.PatternLayout
log4j.appender.debugLog.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.appender.reportsLog=org.apache.log4j.FileAppender
log4j.appender.reportsLog.File=logs/reports.log
log4j.appender.reportsLog.layout=org.apache.log4j.PatternLayout
log4j.appender.reportsLog.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.category.debugLogger=TRACE, debugLog
log4j.additivity.debugLogger=false
log4j.category.reportsLogger=DEBUG, reportsLog
log4j.additivity.reportsLogger=false
Then configure the loggers in the Java code accordingly:
static final Logger debugLog = Logger.getLogger("debugLogger");
static final Logger resultLog = Logger.getLogger("reportsLogger");
Do you want output to go to stdout? If not, change the first line of log4j.properties to:
log4j.rootLogger=OFF
and get rid of the stdout lines.
Modify your log4j.properties file accordingly:
log4j.rootLogger=TRACE,stdout
...
log4j.logger.debugLog=TRACE,debugLog
log4j.logger.reportsLog=DEBUG,reportsLog
Change the log levels for each logger depending to your needs.