log4j. Unique log-file name - java

How I can create a uniquely named log file using log4j?. When I used Logback, I can do it like this:
<!-- current time formatted as "yyyyMMdd'T'HHmmss". This value will be available to all
subsequent configuration elements. -->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" />
and inside logger appender define file name pattern:
<file>${bySecond}.log</file>

I believe there's no support for this feature in log4j 1.7 out of the box. But you can extend RollingFileAppender's setFile method by altering fileName parameter to support the time-based feature.

the DailyRollingFileAppender appends the current date afer rolling over to the next file, so you get a unique name ending with the date of the log for every file.
Cite JavaDoc:
For example, if the File option is set to /foo/bar.log and the
DatePattern set to '.'yyyy-MM-dd, on 2001-02-16 at midnight, the
logging file /foo/bar.log will be copied to /foo/bar.log.2001-02-16
and logging for 2001-02-17 will continue in /foo/bar.log until it
rolls over the next day.
add something like this to your properties XML file:
<appender name="roll" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="application.log" />
<param name="DatePattern" value=".yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MMM-dd HH:mm:ss,SSS} [%t] %c %x%n %-5p %m%n"/>
</layout>
</appender>

Related

log4j: archived files removing policy

I'm using TimeBasedRollingPolicy and RollingFileAppender to have a my logs rolling over and be archived as myLogFileName..log.gz:
<appender class="org.apache.log4j.rolling.RollingFileAppender" name="myLogFile">
<param value="/var/log/my/myLogFileName.log" name="File"/>
<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
<param name="FileNamePattern" value="/var/log/my/myLogFileName.%d.log.gz" />
</rollingPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param value="%d [%t] %-5p - %m%n" name="ConversionPattern"/>
</layout>
</appender>
What I don't understand - is where it is defined when and how really old archived files will be totally removed from the filesystem?
And, if I want to keep always only no older than one month old files - where I can set it up (using log4j (extras))?
TimeBasedRollingPolicy is defined by apache-log4j-extras. This dependency will need to be on the classpath in order to use that policy.
RollingFileAppender includes a maxBackupIndex property, which specifies the maximum number of rolled over backup files to retain. However, I don't believe this property is supported when using a TimeBasedRollingPolicy. This means that, when using RollingFileAppender with the TimeBasedRollingPolicy, old backup files will not be removed by the appender.
If you were using Logback as the logging implementation (perhaps in conjunction wiht SLF4J), then you could achieve the desired outcome using the
Logback RollingPolicy. I acknowledge that the question is seeking a log4j solution, but I'm not aware one.

Create log file with date using log4j

I'm writing my log file using below code but it stores file as QueryLog.log. Am i missing something? Check my code of log4j.properties file
log4j.logger.org.hibernate=INFO
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE
log4j.logger.org.hibernate.hql.ast.AST=info
log4j.logger.org.hibernate.tool.hbm2ddl=warn
log4j.logger.org.hibernate.hql=debug
log4j.logger.org.hibernate.cache=info
log4j.logger.org.hibernate.jdbc=debug
log4j.rootLogger = DEBUG, FILE
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.DatePattern='.'yyyy-MM-dd-a
log4j.appender.FILE.File=log4j/QueryLog.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern= %d{HH:mm:ss} %-5p %c - %m%n
Links i used:
http://www.tutorialspoint.com/log4j/log4j_logging_files.htm
http://www.codejava.net/coding/configure-log4j-for-creating-daily-rolling-log-files
As is mentioned in this StackOverflow Q&A, the purpose of a RollingFileAppender is to automatically create a new log file at some defined interval. In the case of the DailyRollingFileAppender, that interval is 12:00 AM of each day.
What this means is that the first file created by log4j will have the file name you specified here:
log4j.appender.FILE.File=log4j/QueryLog.log
And, from then forward, each day a new log file will be created with the date appended to it.
To always name the file with the date appended, you could use DatedFileAppender by Geoff Mottram
This line sets the log file name, in your log4j properties you have:
log4j.appender.FILE.File=log4j/QueryLog.log
You can see the answer here
Setting a log file name to include current date in Log4j
The solution to log directly to a file with current active date/time such as XYZ.log.20150101.log instead of XYZ.log could be done by simply removing ActiveFileName property when using the rolling package org.apache.log4j.rolling.RollingFileAppender in the apache-log4j-extras 1.1 with log4j 1.2.x.
<appender name="defaultFileAppender" class="org.apache.log4j.rolling.RollingFileAppender">
<param name="append" value="true" />
<param name="Threshold" value="INFO" />
<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
<param name="FileNamePattern"
value="${catalina.base}/logs/application/custom-application-logger.%d{yyyy-MM-dd_HH_mm}" />
</rollingPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %-10t [%-40.40c] %x - %m%n" />
</layout>
</appender>

Use system properties OR variables in log4j

I want to to do like this:
<appender name="ErrorLog" class="org.apache.log4j.FileAppender">
<param name="File" value="${error.log.path}"/>
<param name="Append" value="true" />
<param name="Threshold" value="ERROR"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%C{1} %L [%t] %d{dd MMM,yyyy HH:mm:ss.SSS} %-5p - %m%n" />
</layout>
</appender>
Notice this line: <param name="File" value="${error.log.path}"/>
I tried to set the values like this:
public static void main(String[] args) {
System.setProperty("error.log.path", "/test/crm/log/error.log");
ApplicationContext context = new ClassPathXmlApplicationContext("blah.xml");
..........
..........
}
But I don't see any effect.
Is log4j gets configured before calling the main method?
Is there any other way to do this?
Look at this thread
It looks like you did everything right. I don't think there is any difference between setting the property inside your main class with System.setProperty() and specifying it via the command line as long as it happens befor actual log4j initialization.
I think your issue is that your logging framework gets loaded before you specify the property.
I can say that the logging framework (log4j) will get configured when you call the configurator. Stuff like BasicConfigurator.configure() (in your case its xml configurator).
Otherwise the first attempt to use the logging will cause message like "log4j is not configured properly".
The real question is whether your code snippet with 'main' is not oversimplified.
With this in mind, another question that I have to ask - whether you're running inside some container or you're running a real vanilla method main and configure everything by yourself? I'm asking because if you're running in container, the chances are that container will by itself somehow configure its logging, for example JBoss will do so. In this case more investigation is required.
Hope this helps
You can do it by configure appender pragmatically
FileAppender fa = new FileAppender();
fa.setFile("/test/crm/log/error.log");
fa.setLayout(new
PatternLayout("%C{1} %L [%t] %d{dd MMM,yyyy HH:mm:ss.SSS} %-5p - %m%n"));
fa.setThreshold(Level.ERROR);
fa.setAppend(true);
fa.activateOptions();
Logger.getRootLogger().addAppender(fa);
// similarly you can add all appenders.
// or just append file name alone
Logger log = Logger.getLogger(YourClass.class);
FileAppender appender = (FileAppender) log.getAppender("ErrorLog");
appender.setFile("appender");
System Properties can be used as ${user.home}, pick required from here http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
example :
<appender name="errorLog" class="com.qait.logger.IOPFileAppender">
<param name="Threshold" value="ERROR" />
<param name="File"
value="${user.home}/Harvestors/IOP Error Logs/error.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d%-5p [%c{1}] %m %n" />
</layout>
<filter class="org.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ERROR" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter" />
</appender>
Access to your property via "sys:" prefix.
Example:
<param name="File" value="${sys:error.log.path}"/>
For more information follow this link: https://logging.apache.org/log4j/2.x/manual/lookups.html
maven document:
System properties. The formats are ${sys:some.property} and ${sys:some.property:-default_value}.
from Maven Property Substitution
Setting the system property does not come into affect here. You'll need to pass it as a argument to java while executing. Try
java -Derror_log_path=/test/crm/log/error.log
Note: I am not sure if dot . works in there so replaced it with underscore _.

Best way to modify log4j appended for logging

I'm currently developing soon to be big(functional wise) rest web service and I want to capture logs really good, so I can have a good insight of what is going on where. For now I use log4j for logging, using this appended setting :
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
which produces these kind of logs :
10:44:55,893 INFO [STDOUT] INFO : my.package.MyClass - I'm class message
How can I make this message look like i.e.
10:44:55,893 INFO : my.package.MyClass - I'm class message
Can I make a special appender or whatever it is, and use it in some classes not in all, i.e. I want to have in few of my logs this :
Payload: some request parameters
Response: some response that my service returns
extra data : some extra data
Without having these INFO [STDOUT] INFO my.package.MyClass in front of it
UPDATE
I forgot to mention in the question that I'm using Jboss 5. I think the jboss might be adding the 10:44:55,893 INFO [STDOUT] to any format that I put in my log4j config.
BOUNTY UPDATE
I changed this :
<!-- ============================== -->
<!-- Append messages to the console -->
<!-- ============================== -->
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
to this:
<!-- ============================== -->
<!-- Append messages to the console -->
<!-- ============================== -->
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%m%n"/>
</layout>
</appender>
And it worked, but it seems kind of ugly to do it like this. Is there any other way? I'm using spring MVC/JBoss combination.
I'm now getting nice clean messages :
10:44:55,893 INFO : my.package.MyClass - I'm class message
without annoying
10:44:55,893 INFO [STDOUT]
prefix
Question 1:
Use the following pattern layout for your appender:
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p: %c - %m%n" />
The conversion pattern in the configuration file you stated does not result in the kind of log you stated. For example the date/time is not included in your conversion pattern.
Question 2:
You can use a special logger which uses another appender that is only logging the pure message.
Your configuration would for example look like the following:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n" />
</layout>
</appender>
<appender name="consoleAppender2" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p: %c - %m%n" />
</layout>
</appender>
<logger name="specialLogger" additivity="false">
<level value="INFO" />
<appender-ref ref="consoleAppender" />
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="consoleAppender2" />
</root>
</log4j:configuration>
You use the specialLogger for the pure messages without the additional information. It can be used in multiple classes.
In the configuration of the specialLogger, additivity = "false" is needed, because otherwise also the appender consoleAppender2 of the root logger would log the same message. (The message would be logged two times in this case.)
Your code could for example look like this:
public class TestClassA
{
private static Logger specialLogger = Logger.getLogger("specialLogger");
private static Logger logger = Logger.getLogger(TestClassA.class);
public TestClassA() {
}
public void doSomething() {
logger.info("Some message from TestClassA");
specialLogger.info("Some message via the specialLogger from TestClassA");
}
}
Calling doSomething results in:
17:17:18,125 INFO : com.foo.TestClassA - Some message from TestClassA
Some message via the specialLogger from TestClassA
Somewhere in your main class you need to configure log4j as usual, e.g.:
DOMConfigurator.configureAndWatch("log4j.xml", 60 * 1000);
The INFO [STDOUT] normally comes from log4j listening for System.out as well. We had a similiar case where the application itself had its own log4j configuration and thus got its own root appender. This would log to the console which is listened to by the JBoss log4j. This in turn adds the INFO [STDOUT] as if you were writing directly to System.out (or ERROR [STDERR] when writing to System.err).
The solution in our case was to remove the application specific log4j config and just use the one that JBoss writes to.
Another way might be to directly write to an application specific log file rather than writing to the console. In a server environment you'd most probably refer to log files anyway.
As for the second part, i.e. automatically extending logs with response, request etc. data:
In one case we had a super class for stateless session beans that provided logging functionality and had a (overwritable) logger per instance. The base methods like info would then call the logger and add the required data automatically.
A second approach could be MCD, i.e. you put some data (like the request) into the thread local MDC (basically a map) and then access them in your pattern definition.
For example, we have several similar applications each of which has some classes the others have too. So we'd need which application the message originated from and thus added the application name to the MDC:
In the code:
MDC.put("app.name", "myapplication");
In the log4j pattern config:
<param name="ConversionPattern" value="%d %-5p [%c (%X{app.name})] %m%n"/> (note the %X{app.name})
I didn't test whether you could do something like putting the request into the MDC and then use : %X{request.getAttribute('xyz')} but if it just gets the value in the MDC and calls toString() on it, you might create a request wrapper like this:
class RequestLogWrapper {
private HttpServletRequest request; //initialize through constructor etc.
public String toString() {
return request.getAttribute("xyz") + ";" + request.getAttribute("abc") + ... //handle null etc. as well
}
}
Then call MDC.put("request", new RequestLogWrapper(request)); and in the config use %X{request}.
Try to use this pattern as it will give you clean message:
<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %c %X %m/>
It is a good idea to add some unique value to MDC when request comes in, then add %X{uniqueValueKey} to your pattern. It will allow you to track logs for this unique request.
If you do not like the log4j xml configuration file you could switch to a property file instead. You cannot configure filters using the simple property file but since it seems you don't need them this shouldn't be an issue.
Given that you're
...currently developing soon to be big(functional wise) rest web service and I want to capture logs really good, so I can have a good insight of what is going on where.
then I'm afraid that your desired output won't give you many insights at all, it won't scale well, and it will make you loose your mind once the application gets big as expected...
Please refer to Log4j Best Practices for a good reference of logs design. Please take a look at ALL its paragraphs including the cosmetic consideration at the very end. Hope this helps.
to print only messages , the following conversion pattern will do.
<param name="ConversionPattern" value="%m%n"/>
Depending on your requirement, you can set the conversion pattern to whatever you want to
%-5p refers to the type of log entry. This would appear in the
log file as INFO, DEBUG, ERROR, etc. Technically, %p would be enough
to include this description; the -5 is there to include the word in
a 5-character width column.
%d refers to the date.
%t to the name of the thread that raised this log entry.
%c lists the category that generated this log which usually is the
class name.
%m displays the message
%n adds a carriage return.
Are you going to put all relevant information in messages only? I am not sure but its not a good idea.

Log4j: How to configure simplest possible file logging?

My story:
I want to make a thing which is as simple as a simplest possible log4j logger that logs rows to a file. I have found several examples with some functionality, but not a basic, general one that really works, and not one with an explanation how the each row work.
Question:
Could anybody provide one?
Prerequisites:
I already know where to put the file and I have the log4j configured and working for console logging.
Now I want to log to a file and also find the file from file system once the program has run.
Rows needed to be added to the existing log4j.properties file are the desired output.
I have one generic log4j.xml file for you:
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration debug="false">
<appender name="default.console" class="org.apache.log4j.ConsoleAppender">
<param name="target" value="System.out" />
<param name="threshold" value="debug" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
</layout>
</appender>
<appender name="default.file" class="org.apache.log4j.FileAppender">
<param name="file" value="/log/mylogfile.log" />
<param name="append" value="false" />
<param name="threshold" value="debug" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
</layout>
</appender>
<appender name="another.file" class="org.apache.log4j.FileAppender">
<param name="file" value="/log/anotherlogfile.log" />
<param name="append" value="false" />
<param name="threshold" value="debug" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
</layout>
</appender>
<logger name="com.yourcompany.SomeClass" additivity="false">
<level value="debug" />
<appender-ref ref="another.file" />
</logger>
<root>
<priority value="info" />
<appender-ref ref="default.console" />
<appender-ref ref="default.file" />
</root>
</log4j:configuration>
with one console, two file appender and one logger poiting to the second file appender instead of the first.
EDIT
In one of the older projects I have found a simple log4j.properties file:
# For the general syntax of property based configuration files see
# the documentation of org.apache.log4j.PropertyConfigurator.
# The root category uses two appenders: default.out and default.file.
# The first one gathers all log output, the latter only starting with
# the priority INFO.
# The root priority is DEBUG, so that all classes can be logged unless
# defined otherwise in more specific properties.
log4j.rootLogger=DEBUG, default.out, default.file
# System.out.println appender for all classes
log4j.appender.default.out=org.apache.log4j.ConsoleAppender
log4j.appender.default.out.threshold=DEBUG
log4j.appender.default.out.layout=org.apache.log4j.PatternLayout
log4j.appender.default.out.layout.ConversionPattern=%-5p %c: %m%n
log4j.appender.default.file=org.apache.log4j.FileAppender
log4j.appender.default.file.append=true
log4j.appender.default.file.file=/log/mylogfile.log
log4j.appender.default.file.threshold=INFO
log4j.appender.default.file.layout=org.apache.log4j.PatternLayout
log4j.appender.default.file.layout.ConversionPattern=%-5p %c: %m%n
For the description of all the layout arguments look here: log4j PatternLayout arguments
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="INFO" />
<param name="File" value="sample.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="fileAppender" />
</root>
</log4j:configuration>
Log4j can be a bit confusing. So lets try to understand what is going on in this file:
In log4j you have two basic constructs appenders and loggers.
Appenders define how and where things are appended. Will it be logged to a file, to the console, to a database, etc.? In this case you are specifying that log statements directed to fileAppender will be put in the file sample.log using the pattern specified in the layout tags. You could just as easily create a appender for the console or the database. Where the console appender would specify things like the layout on the screen and the database appender would have connection details and table names.
Loggers respond to logging events as they bubble up. If an event catches the interest of a specific logger it will invoke its attached appenders. In the example below you have only one logger the root logger - which responds to all logging events by default. In addition to the root logger you can specify more specific loggers that respond to events from specific packages. These loggers can have their own appenders specified using the appender-ref tags or will otherwise inherit the appenders from the root logger. Using more specific loggers allows you to fine tune the logging level on specific packages or to direct certain packages to other appenders.
So what this file is saying is:
Create a fileAppender that logs to
file sample.log
Attach that appender to the root
logger.
The root logger will respond to any
events at least as detailed as
'debug' level
The appender is configured to only
log events that are at least as
detailed as 'info'
The net out is that if you have a logger.debug("blah blah") in your code it will get ignored. A logger.info("Blah blah"); will output to sample.log.
The snippet below could be added to the file above with the log4j tags. This logger would inherit the appenders from <root> but would limit the all logging events from the package org.springframework to those logged at level info or above.
<!-- Example Package level Logger -->
<logger name="org.springframework">
<level value="info"/>
</logger>
Here's a simple one that I often use:
# Set up logging to include a file record of the output
# Note: the file is always created, even if there is
# no actual output.
log4j.rootLogger=error, stdout, R
# Log format to standard out
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= %5p\t[%d] [%t] (%F:%L)\n \t%m%n\n
# File based log output
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=owls_conditions.log
log4j.appender.R.MaxFileSize=10000KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern= %5p\t[%d] [%t] (%F:%L)\n \t%m%n\n
The format of the log is as follows:
ERROR [2009-09-13 09:56:01,760] [main] (RDFDefaultErrorHandler.java:44)
http://www.xfront.com/owl/ontologies/camera/#(line 1 column 1): Content is not allowed in prolog.
Such a format is defined by the string %5p\t[%d] [%t] (%F:%L)\n \t%m%n\n. You can read the meaning of conversion characters in log4j javadoc for PatternLayout.
Included comments should help in understanding what it does. Further notes:
it logs both to console and to file; in this case the file is named owls_conditions.log: change it according to your needs;
files are rotated when they reach 10000KB, and one back-up file is kept
Here is a log4j.properties file that I've used with great success.
logDir=/var/log/myapp
log4j.rootLogger=INFO, stdout
#log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.DailyRollingFileAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{MM/dd/yyyy hh:mm:ss a}|%-5p|%-30c{1}| %m%n
log4j.appender.stdout.DatePattern='.'yyyy-MM-dd
log4j.appender.stdout.File=${logDir}/myapp.log
log4j.appender.stdout.append=true
The DailyRollingFileAppender will create new files each day with file names that look like this:
myapp.log.2017-01-27
myapp.log.2017-01-28
myapp.log.2017-01-29
myapp.log <-- today's log
Each entry in the log file will will have this format:
01/30/2017 12:59:47 AM|INFO |Component1 | calling foobar(): userId=123, returning totalSent=1
01/30/2017 12:59:47 AM|INFO |Component2 | count=1 > 0, calling fooBar()
Set the location of the above file by using -Dlog4j.configuration, as mentioned in this posting:
java -Dlog4j.configuration=file:/home/myapp/config/log4j.properties com.foobar.myapp
In your Java code, be sure to set the name of each software component when you instantiate your logger object. I also like to log to both the log file and standard output, so I wrote this small function.
private static final Logger LOGGER = Logger.getLogger("Component1");
public static void log(org.apache.log4j.Logger logger, String message) {
logger.info(message);
System.out.printf("%s\n", message);
}
public static String stackTraceToString(Exception ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
return sw.toString();
}
And then call it like so:
LOGGER.info(String.format("Exception occurred: %s", stackTraceToString(ex)));

Categories

Resources