I have simple question.
How to have log file name dynamically supplied from code?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="${logfilename}.log"
filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="6" modulate="true"/>
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
Here file name is logs/app.log.
How to make it dynamic with date and time appended as well in file name? Though pattern is applied but it doesn't work.
Here logs is the directory which log4j library automatically creates, can it be dynamic as well?
EDIT In parameter fileName I have placed ${logfilename}.log and setting system property as below:
System.setProperty("logfilename", "a_cool_logname");
Now it is creating file with name ${logfilename}.log which is definitely not required.
Thanks
**Property File Look like this **
log4j.rootLogger=DEBUG, FA
#Console Appender WE WRE NOT USING IT
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=%d{dd MM yy HH:mm} %-5p %m%n
#File Appender
log4j.appender.FA=org.apache.log4j.FileAppender
log4j.appender.FA.File=${fName}
#log4j.appender.FA.MaxFileSize=5MB
#log4j.appender.FA.MaxBackupIndex=3
log4j.appender.FA.layout=org.apache.log4j.PatternLayout
log4j.appender.FA.layout.ConversionPattern=%d{dd MM yy HH:mm} %8p %10m%n
# Set the logger level of File Appender to WARN
log4j.appender.FA.Threshold = INFO
log4j.appender.FA.Threshold = DEBUG
**And set Properties in JAVA **
System.setProperty("fName", "d:\\siemens\\" + getDateTime() + c.getSimpleName() +".log");
PropertyConfigurator.configure("log4j.properties");
let me know if u need further query thanks
Related
I'm very new with log4j2 but, I have this application that used log4j and I had to change it to the log4j2 version.
The log file is being created but it's always empty, this project doesn't use maven so I don't have any pom.xml, I just have my log4j2.xml which look like this:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="archive" fileName="/${sys:ENTORNO}/online/es/web/logs/WebSeal_EAI${sys:cloneId}.log"
filePattern="/${sys:ENTORNO}/online/es/web/logs/WebSeal_EAI${sys:cloneId}.log.%d{yyyy-MM-dd}.gz">
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %log{36} - %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" />
</Policies>
</RollingFile>
<Console name="screen" target="SYSTEM_OUT">
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %log{36} - %m%n</Pattern>
</PatternLayout>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="archive"/>
</Root>
</Loggers>
</Configuration>
And in java, I load the configuration like this:
File file = new File(log4Jcfg);
ConfigurationFactory factory = XmlConfigurationFactory.getInstance();
ConfigurationSource configurationSource = new ConfigurationSource(new FileInputStream(new File(log4Jcfg)));
Configuration configuration = factory.getConfiguration(context, configurationSource);
context = new LoggerContext("JournalDevLoggerContext");
context.start(configuration);
log4Jcfg has the xml path. The file it's created but it's always empty and I truly don't know why.
I have been reading a lot of questions like this, and tried almost everything (I think) as I put the .xml in the classpath, I changed a few things about the xml but none of that worked for me.
Anyone knows what is happening, I mean, if the file is created, why it doesn't print anything?
Is it something wrong with the .xml or the java code where I load the configuration?
Also, this project is with the server Websphere v9.0.
Thank you so much.
I case someone has this same problem, I've just solved it.
The problem was the way I was loading the xml config; I've changed it like this:
LoggerContext ctx = getLoggerContext();
ConfigurationSource configurationSource = new ConfigurationSource(new FileInputStream(new File(log4Jcfg)));
ctx.start(ConfigurationFactory.getInstance().getConfiguration(ctx, configurationSource));
and now it works perfect!
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
We have WAR deployments running on Tomcat containers which are using log4j 2.5 for logging events. We have now amended the deployments' log4j2.xml configuration to have the log files roll over every 24 hours but, with this new configuration, the rollover of files are not taking place as we would expect.
Sample configuration:
<RollingFile name="file"
fileName="${sys:catalina.base}/logs/${web:contextPath}.log"
filePattern="${sys:catalina.base}/logs/${web:contextPath}-%d{dd-MMM-yyyy}.log"
append="true">
<PatternLayout pattern="%d{dd-MMM-yyyy HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" >
<header>LOG START DATE=${date:dd-MMM-yyyy HH:mm:ss.SSS} APP=${web:contextPath} TOMCAT=${env:HOSTNAME}:${env:CONNECTOR_PORT}${sys:line.separator}</header>
<footer>LOG END DATE=${date:dd-MMM-yyyy HH:mm:ss.SSS} APP=${web:contextPath} TOMCAT=${env:HOSTNAME}:${env:CONNECTOR_PORT}${sys:line.separator}</footer>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
Any ideas why the rollover is not taking place?
NOTE: The same configuration but with a <CronTriggeringPolicy schedule="0 0 0 * * ?" /> instead of TimeBasedTriggeringPolicy does rollover but, in this case, the rolled over files get created with today's date in the filename and NOT yesterday's date.
NOTE2: We have other deployments with similar configuration that do rollover every 24 hours but those configurations have the filename hardcoded instead of using ${web:contextPath}. Could this lookup have something to do with why RollingFile might not work?
--- EDIT ---
UPDATE: We are able to get TimeBasedTriggeringPolicy to rollover files using above configuration when the Tomcat instance is running on Windows but NOT when the Tomcat instance is running on Linux.
There is nothing wrong with your configuration snippet as I get the desired behaviour of time based rolling.
To test, I changed the dd-MMM-yyyy to dd-MMM-yyyy-HH-mm and my log file rolls every minute.
It must be something else that is preventing you from achieving the desired behaviour.
My setup #1:
Log4j2 v2.8.2
Apache Tomcat 8.5.13
Windows 7 Enterprise SP1
My setup #2:
Log4j2 v2.5
Apache Tomcat 7.0.77
CentOS 7 (1611)
I have the following 3 JARs in WEB-INF/lib:
log4j-api-2.5.jar
log4j-core-2.5.jar
log4j-web-2.5.jar
Here is my complete log4j2.xml for your reference:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Appenders>
<RollingFile name="RollingFileAppender"
fileName="${sys:catalina.base}/logs/${web:contextPath}.log"
filePattern="${sys:catalina.base}/logs/${web:contextPath}-%d{dd-MMM-yyyy-HH-mm}.log"
append="true">
<PatternLayout pattern="%d{dd-MMM-yyyy HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" >
<header>LOG START DATE=${date:dd-MMM-yyyy HH:mm:ss.SSS} APP=${web:contextPath} TOMCAT=${env:HOSTNAME}:${env:CONNECTOR_PORT}${sys:line.separator}</header>
<footer>LOG END DATE=${date:dd-MMM-yyyy HH:mm:ss.SSS} APP=${web:contextPath} TOMCAT=${env:HOSTNAME}:${env:CONNECTOR_PORT}${sys:line.separator}</footer>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="root" level="debug" additivity="false">
<appender-ref ref="RollingFileAppender" level="debug"/>
</Logger>
<Root level="debug" additivity="false">
<AppenderRef ref="RollingFileAppender"/>
</Root>
</Loggers>
</Configuration>
We are using log4j2 on Window 7 Enterprise.
JBoss Developer Studio 8(this really doesn't matter)
RollingFileAppender rolls over the log files properly, however the original log file keep old logs and continues to increase in size. There is a JIRA bug (LOG4J2-904) related to this . I followed some of the options like
fileIndex="min" or fileIndex="max"
Using RollingRandomAccessFile instead of RollingFile.
Some comments indicated problem fixed as of log4j 2.4.1 version. However, I am still seeing the same problem in log4j 2.5.
I tried logging to both RollingFile and RollingRandomAccessFile appenders at the same time. An image of the log folder in included Here is the image of Log folder from rollover
Here is my log4j2.xml
<Configuration>
<Properties>
<property name="appname">myapp</property>
<Property name="log-path">${server.dir}/myapp</Property>
</Properties>
<Appenders>
<RollingFile name="DATED_ROLLING_FILE" fileName="${log-path}/${myapp}.log" filePattern="${log-path}/${myapp}_%d{MM-dd-yyyy}-%i.log" maxFileSize="40 KB">
<PatternLayout>
<Pattern>%d: %-5p [%c{1}]:%L - %M %m%n</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="40 KB" />
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="100" />
</RollingFile>
<RollingRandomAccessFile name="DATED_RAC_APPENDER" fileName="${log-path}/epermitsrac.log"
filePattern="${log-path}/epermitsrac_%d{MM-dd-yyyy}-%i.log" >
<PatternLayout>
<Pattern>%d: %-5p [%c{1}]:%L - %M %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="40 KB" />
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="100" />
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="DATED_ROLLING_FILE" />
<AppenderRef ref="DATED_RAC_APPENDER" />
</Root>
</Loggers>
</Configuration>
Here is the image of Log folder from rollover. As you can see it does not clear the original File.
Did anyone else experienced same problem and is there a fix for this.
I have tried with below configuration and it is working fine, except that the latest file will be with out date.
the log4j2.properties configuration
rootLogger.level = all
appenders = rolling, console
status = warn
appender.console.type = Console
appender.console.name = console
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d [%-5p] (%F:%M:%L) %m%n
# Rolling file based on date for day wise
appender.rolling.type = RollingFile
appender.rolling.name = rolling
#if i use below file name the rollover will not happenning as expected
#appender.rolling.fileName = E:/LOGS/${date:yyyyMMdd}_test.log
#with below filename name the rollover will happen as expected
appender.rolling.fileName = E:/LOGS/test.log
appender.rolling.filePattern = E:/LOGS/%d{yyyyMMdd}_test.log
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d [%-5p] [%F:%M:%L] %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
#use below for day wise roll over
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
rootLogger.appenderRefs = rolling, console
rootLogger.appenderRef.console.ref = console
rootLogger.appenderRef.rolling.ref = rolling
rootLogger.appenderRef.stdout.ref = console, rolling
I'm using log4j 2.0-beta9. I have a question about the SMTP appender. I need to configure the subject, from and to values from properties. I'm logging a MapMessage and my config is as below -
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="DEBUG">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%t] %-5p %c - %m%n"/>
</Console>
<SMTP name="Mail" subject="Error Log for ${env:HOSTNAME}" to="${sys:mail.to}" from="${sys:mail.from}"
smtpHost="${sys:mail.host}" smtpPort="${sys:mail.port}" smtpDebug="true" bufferSize="1">
<PatternLayout>
<pattern>%d [%t] %-5p %c - %m%n</pattern>
</PatternLayout>
</SMTP>
<Async name="AsyncMail">
<appender-ref ref="Mail" />
</Async>
</appenders>
<loggers>
<root level="info">
<appender-ref ref="Console"/>
<appender-ref ref="AsyncMail">
<MapFilter onMatch="ACCEPT" onMismatch="DENY">
<KeyValuePair key="throwable.class" value="java.lang.RuntimeException" />
</MapFilter>
</appender-ref>
</root>
</loggers>
</configuration>
// Java Code to log the msg
Throwable throwable; // this is the exception that is thrown by the app.
MapMessage message = new MapMessage();
message.put("throwable.message", throwable.getMessage());
message.put("throwable.class", throwable.getClass().getName());
message.put("throwable.stacktrace", ExceptionUtils.getStackTrace(throwable)); // ExceptionUtils from apache-commons
LOGGER.error(message, throwable); // org.apache.logging.log4j.Logger
The problem is that none of these values are replaced dynamically. Is there any way to do this?
Thanks in advance.
You need to set the mail.to and mail.from System properties. The problem you're having might be that you're running in a Servlet 3.0 environment, in which case the Log4j2.xml file is being processed before your code that sets the properties is executed.
If that is the case, you can create a servlet container initializer that you configure in your web.xml file to load before Log4j2's servlet container initializer is loaded.