Configure Log4J to write new file every day new log file - java

I have this basic configuration of Log4J:
Logger log = Logger.getLogger(LogMessages.class.getName());
BasicConfigurator.configure(); // Basic configuration for Log4J 1.x
ConsoleAppender console = new ConsoleAppender(); //create appender
//configure the appender
String PATTERN = "%d [%p|%c|%C{1}] %m%n";
console.setLayout(new PatternLayout(PATTERN));
console.setThreshold(Level.FATAL);
console.activateOptions();
//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(console);
FileAppender fa = new FileAppender();
fa.setName("FileLogger");
fa.setFile("log" + File.separator + "messages.log");
fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fa.setThreshold(Level.DEBUG);
fa.setAppend(true);
fa.activateOptions();
//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(fa); //repeat with all other desired appenders
// BASIC TEST
log.info("Some message 1");
log.info("Some message 2");
log.info("Some message 3");
log.info("Some message 4");
How I can configure Log4J to create a new file everyday and write messages into the file?

Use org.apache.log4j.DailyRollingFileAppender instead of FileAppender.
Details about settings can be found here.
EDIT
PatternLayout layout = new PatternLayout();
String conversionPattern = "[%p] %d %c %M - %m%n";
layout.setConversionPattern(conversionPattern);
// creates daily rolling file appender
DailyRollingFileAppender rollingAppender = new DailyRollingFileAppender();
rollingAppender.setFile("app.log");
rollingAppender.setDatePattern("'.'yyyy-MM-dd");
rollingAppender.setLayout(layout);
rollingAppender.activateOptions();
// configures the root logger
Logger rootLogger = Logger.getRootLogger();
rootLogger.setLevel(Level.DEBUG);
rootLogger.addAppender(rollingAppender);
// creates a custom logger and log messages
Logger logger = Logger.getLogger(My.class);
logger.debug("this is a debug log message");
logger.info("this is a information log message");
logger.warn("this is a warning log message");

Related

Log4j2 logs are not directing to correct log file

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.

Getting Log4j2 errors

My log4j2 properties file:
status = warn
name= properties_configuration
#Directory path where log files will be stored
property.basePath = ./log/
#File logger
appender.rolling.type = RollingFile
appender.rolling.name = fileLogger
appender.rolling.fileName= ${basePath}app.log
appender.rolling.filePattern= ${basePath}app_%d{yyyyMMdd}.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %msg%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.delete.type = Delete
appender.rolling.strategy.delete.basePath = ${basePath}
appender.rolling.strategy.delete.maxDepth = 1
appender.rolling.strategy.delete.ifLastModified.type = IfLastModified
appender.rolling.strategy.delete.ifLastModified.age = 30d
#Root logger configuration
rootLogger.level = info
rootLogger.additivity = false
rootLogger.appenderRef.rolling.ref = fileLogger
I'm using Lombok #Log4j2 annotation:
#Log4j2
public class BotApplication {
public static void main(String[] args) {
ApiContextInitializer.init();
TelegramBotsApi telegram = new TelegramBotsApi();
Bot bot = new Bot();
try {
telegram.registerBot(bot);
log.info("Bot successfully connected.");
} catch (TelegramApiRequestException e) {
log.error("Can't start Bot. Error: {}", e.getMessage());
}
}
}
Application writes logs to file correctly, but always when i run my app i got errors in my console:
log4j:WARN No appenders could be found for logger (org.apache.http.client.protocol.RequestAddCookies).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Seems that these errors don't affect to the logger, but I would like to remove them somehow.
Error messages that being with "log4j:WARN" are coming from log4j 1.x. This error means you have the log4j 1.x jar in your classpath but do not have a Log4j 1.x configuration present.
If you do not want to use log4j 1 (and you shouldn't) then add the log4j-1.2-api jar from Log4j 2 to your project.

log4j2 doesn't save to log file

I have configuration for log4j2 in properties file. Logger sends output to the console but not to the file. It creates log file but it doesn't update it with content. What can be missing in my configuration file?
log4j2.properties
status = error
name = PropertiesConfig
property.filename = /usr/local/logs/kit.log
filters = threshold
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appenders = rolling
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}
appender.rolling.filePattern = debug-backup-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=10MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 20
loggers = rolling
logger.rolling.name = org.kit
logger.rolling.level = debug
logger.rolling.additivity = false
logger.rolling.appenderRef.rolling.ref = RollingFile
Test class
package org.kit.log;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LogTest {
private static final Logger logger = LogManager.getLogger(LogTest.class);
public static void main(String[] args) {
logger.debug("Hello world - debug log");
logger.info("Hello world - info log");
logger.warn("Hello world - warn log");
logger.error("Hello world - error log");
}
}
You can try setting the first line in the configuration to status = TRACE to show Log4j2 internal logging on the console. This may help determine any problems with the configuration.
Also, can you try configuring a rootLogger instead of a named logger?
rootLogger.level = info
rootLogger.appenderRef.rolling.ref = RollingFile

Log4j 2: How to add references from my classes in my log4j.properties [duplicate]

This question already has answers here:
Log4j Log at all Classes Level
(2 answers)
Closed 6 years ago.
is my first question, sorry If I make a mistake asking my question.
Well this is my doubt about log4j2.(I use spring framework java)
My goal is write in a FILE all logs generated in classes wich have a Logger instance.
For this purpose I have the following log4j.properties file:
name=PropertiesConfig
property.filename = C:/sts-bundle/Tomcat 7.0/logs
appenders = console,rolling
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5level] %d{dd MMM yyyy HH:mm:ss,SSS} [%t] %c{5} - %msg%n
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}/fnelLog-${date:dd-MM-yyyy}.log
appender.rolling.filePattern = ${filename}/fnelLog-%d{dd-MM-yyyy}-%i.log
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = [%-5level] %d{dd MMM yyyy HH:mm:ss,SSS} [%t] %c{5} - %msg%n
appender.rolling.policies.type = Policies
#appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
#appender.rolling.policies.time.interval = 2
#appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=50MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 4
loggers = rolling
############ HERE IS MY PROBLEM, I Only reference to this class, but I want to add another,
############ so I can write all logs in a file described in lines before
logger.rolling.name = fnel.bcp.org.main.TestMain
logger.rolling.level = debug
#logger.rolling.additivity = false
logger.rolling.appenderRefs = rolling
logger.rolling.appenderRef.rolling.ref = RollingFile
rootLogger.level = debug
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT
And Now here are the two clases which I used the Logger interface.
public class FooClass {
private static Logger logger = LogManager.getLogger(FooClass.class);
public void testLog4j() {
// TODO Auto-generated method stub
logger.debug("This is a debug message");
logger.info("This is an info message");
logger.warn("This is a warn message");
logger.error("This is an error message");
logger.fatal("This is a fatal message");
}
}
public class TestMain {
private static Logger logger = LogManager.getLogger(TestMain.class);
public static void main(String[] args) {
FooClass foo = new FooClass();
//Calling foo method
foo.testLog4j();
// TODO Auto-generated method stub
logger.debug("This is a debug message");
logger.info("This is an info message");
logger.warn("This is a warn message");
logger.error("This is an error message");
logger.fatal("This is a fatal message");
}
}
And these are the output in console
So, my question is how can I add FooClass in my log4j.properties file. Because I added next to TestMain class like this " fnel.bcp.org.main.TestMain , fnel.bcp.org.main.FooClass" , but not work.
I tried to separate in different logger.rolling.name, but didn't work too.
Change the line
logger.rolling.name = fnel.bcp.org.main.TestMain
to
logger.rolling.name = fnel.bcp.org.main
this will cause any class in the fnel.bcp.org.main package to be directed to the RollingFile appender. Alternatively, if you want everything in the file you can just remove your logger definition and change the root logger to be directed to RollingFile instead of STDOUT.

How to set file location using BasicConfigurator

I am trying to configure my application not to use log4j.properties, instead use BasicConfigurator to configure everything I have in my log4j.properties. I cannot figure out how to set the location of the file
I tried this with no luck.
Logger log = Logger.getLogger(pjp.getSignature().getDeclaringTypeName());
PatternLayout layout = new PatternLayout();
FileAppender familyservices = new FileAppender();
familyservices.setLayout(layout);
familyservices.setName("com.cambiahealth.engine.rest.family");
familyservices.setFile("/usr/regence/logs/datasvc/v1.0/familyservice.log");
log.addAppender(familyservices);
BasicConfigurator.configure(familyservices);
ConsoleAppender console = new ConsoleAppender(); //create appender
//configure the appender
String PATTERN = "%d [%p|%c|%C{1}] %m%n";
console.setLayout(new PatternLayout(PATTERN));
console.setThreshold(Level.FATAL);
console.activateOptions();
//add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(console);
FileAppender fa = new FileAppender();
fa.setName("FileLogger");
fa.setFile("mylog.log");
fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fa.setThreshold(Level.DEBUG);
fa.setAppend(true);
fa.activateOptions();
/add appender to any Logger (here is root)
Logger.getRootLogger().addAppender(fa)
//repeat with all other desired appenders

Categories

Resources