I want to maintain two Log Files in my web-application using apache Log4j.jar:
1) One log will contain all the Log messages of every level
2) Second log file will contain the Log messages of specific class
This is the configuration XML that I am using: (Not much aware of the tags used in the XML, was just trying out)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="FILE1" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="D:/CSVExportLogs/CSVExportLogFile-ERROR.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c (%F:%L) - %m%n"/>
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="D:/CSVExportLogs/CSVExportLogFile-INFO.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c (%F:%L) - %m%n"/>
</layout>
</appender>
<category name="com.taxware.mgmt.CustomerManager" additivity="false">
<priority value="warn"/>
<appender-ref ref="FILE"/>
</category>
<root>
<priority value="info"/>
<appender-ref ref="FILE1"/>
</root>
</log4j:configuration>
By the above xml I am getting only info messages in the FILE1, I want messages of all levels as well as the message of warn level that are going in the separate file in this file. Is there any solution available for this.
# Create ROOT logger(main logger) with level INFO, and add to it 2 appenders:
# FILE_INFO, FILE_WARN. This means that all loggers by default will writes messages
# in this 2 file appenders, with level INFO or higher
log4j.rootLogger=INFO, FILE_INFO, FILE_WARN
######## LEVELS:
# Set logging level to WARN for all classes and subclasses in package
# com.taxware.mgmt.CustomerManager
log4j.category.com.taxware.mgmt.CustomerManager=WARN
######## APPENDERS:
# FILE_INFO
# Type of appender
log4j.appender.FILE_INFO=org.apache.log4j.RollingFileAppender
# File where to save all messages
log4j.appender.FILE_INFO.File=D:/CSVExportLogs/CSVExportLogFile-INFO.log
# Max file size, after that will be created new log file, and old file will be renamed
log4j.appender.FILE_INFO.MaxFileSize=100KB
# Maximum amount of old log files.
log4j.appender.FILE_INFO.MaxBackupIndex=100
# Patter of messages.
log4j.appender.FILE_INFO.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE_INFO.layout.ConversionPattern=%d{ISO8601} [%-5p][%-24.24t][%32.32c] - %m%n
# Custom level for appender. In this file will be add only messages with level INFO or highter
log4j.appender.FILE_INFO.Threshold=INFO
# FILE_WARN file appender
log4j.appender.FILE_WARN=org.apache.log4j.RollingFileAppender
log4j.appender.FILE_WARN.File=D:/CSVExportLogs/CSVExportLogFile-WARN.log
log4j.appender.FILE_WARN.MaxFileSize=50KB
log4j.appender.FILE_WARN.MaxBackupIndex=10
log4j.appender.FILE_WARN.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE_WARN.layout.ConversionPattern=%d{ISO8601} [%-5p][%-24.24t][%32.32c] - %m%n
# Custom level for appender. In this file will be add only messages with level WARN or highter
log4j.appender.FILE_WARN.Threshold=WARN
For logging the messages of specific class you could do 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="myClassAppender" class="org.apache.log4j.FileAppender">
<param name="File" value="../logs/myClassLogs.log"/>
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n"/>
</layout>
</appender>
.............
<logger name="com.my.package.MySpecificClass">
<!--
all log messages of level "debug" or higher will be logged, unless defined otherwise
all log messages for "MySpecificClass" will be logged to the appender "myClassAppender"
-->
<level value="DEBUG"/>
<appender-ref ref="myClassAppender"/>
</logger>
.............
</log4j:configuration>
Here is the link.
http://veerasundar.com/blog/2011/05/log4j-tutorial-writing-different-log-levels-in-different-log-files/
I say this act in log4j levels:
All < Debug < Info < Warn < Error < Fatal < Off
With your configuration, happen thease:
All logs with "com.taxware.mgmt.CustomerManager" category and "Warn" and smaller level("Error" < Fatal) send for "FILE" appender and don't send for "FILE" appender because you set additivity attribute to false for it.
All logs with any category except "com.taxware.mgmt.CustomerManager" send for "FILE1" appender.
3.You say:"By the above xml I am getting only info messages in the FILE1". You trying logging log with "Warn" or smaller levels(Such as "Error") and "com.taxware.mgmt.CustomerManager" category, you will see result in "FILE" appender and also trying logging with another category and you will see result in "FILE1" appender, except this result is wrong. please do this and say result.
I also suggest you use SLF4J for decoupling API and implementation.
Related
I have a web application which has been logging synchronously using log4j1.2 so far. I am trying to move it to use the async-appender (from log4j 1.2). I have written an XML file - log4j.xml that initializes async-appender. However when I check the logs I see that the ID of the request is not logged (though it used to be logged so far). After some investigation I think that the (key, value) pair for request ID is not present in the MDC anymore.
Is that because async-appender is a separate thread and did not inherit the same key-value pairs as the main application threads?
Is there a way by which I can set these values in the MDC so that the application starts logging request ID again?
log4j.xml file for reference:
<?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="Async" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE"/>
</appender>
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/log/directory/logFile"/>
<param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%-5p] %c %x - %m%n" />
</layout>
</appender>
<root>
<priority value="warn"/>
<appender-ref ref="Async"/>
</root>
</log4j:configuration>
With Async-appender, you need to read the mdcCopy off the LoggingEvent passed into the Async Appender thread. I had a custom PatternLayout which used to try to read request ID and such values from the MDC of the current thread - in essence, it would work only with synchronous logging because the main thread spawning the application threads was setting the values into the respective MDCs.
The Async-appender thread's MDC did not have the (key, value) pairs set, but the LoggingEvents passed to it did have the (key, value) pairs in its mdcCopy.
I am using the org.slf4j.Logger to log output. Output is going to console. How do I get logging logged to a log file?
private static final Logger LOG = LoggerFactory.getLogger(ClassName.class );
LOG.info("Logging output to console");
I am not using a log4j.properties file. I am assuming I will need one.
I added the following log4j.properties file and placed it in different parts of my eclipse project.
# Define the file appender
log4j.appender.FileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.FileAppender.File=logger.log
log4j.appender.FileAppender.layout = org.apache.log4j.PatternLayout
log4j.appender.FileAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
# Direct all messages there
log4j.rootLogger = INFO, FileAppender
I even used
PropertyConfigurator.configure("log4j.properties");
But no logging file appears. log4j.properties doesn't seem to have an effect.
The simplest way, I think, is to define a FileAppender in a log4j.properties file:
# Define the file appender
log4j.appender.FileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.FileAppender.File=[log filename].log
log4j.appender.FileAppender.layout = org.apache.log4j.PatternLayout
log4j.appender.FileAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
# Direct all messages there
log4j.rootLogger = INFO, FileAppender
Just replace [log filename] with some relevant filename. I think Log4j is able to automatically locate the file when you run the project from Eclipse if the file is in your project directory, but I'm not 100% sure. You can use PropertyConfigurator at the start of your application to tell Log4j where to find the properties file, e.g.:
PropertyConfigurator.configure("log4j.properties");
You can create a log4j.xml in the resource folder.
Import log4j package in the class.
Inside the class, instantiate a logger object using Logger.getLogger( ) static method.
Instantiate layouts (readymade or user-defined) to be assigned to appenders.
Instantiate appenders and assign desired layout to them by passing the layout object as parameter to their constructors.
Assign the instatiated appenders to the Logger object by invoking its addAppender( ) method with desired appender as parameter.
Invoke appropriate printing methods on Logger object to perform logging.
.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p [%t] %c{1}.%M(%L) | %m%n" />
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.rolling.RollingFileAppender">
<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
<param name="fileNamePattern" value="/yourfolder/debug_%d{dd-MM-yy}.log" />
</rollingPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p [%t] %c{1}.%M(%L) | %m%n" />
</layout>
</appender>
<root>
<level value="WARN" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</log4j:configuration>
I have only two loggers defined : one is root logger and another one is common logger.
I think then common logger becomes immediate child of root logger right?
if yes, then how to prevent logs printed by common logger's appender to bubble up to root logger's appender?
according to docs :
However, if an ancestor of logger C say P, has the additivity flag set
to false, then C's output will be directed to all the appenders in C
and its ancestors upto and including P but not the appenders in any of
the ancestors of P.
means the logger whose additivity is set to false will have all its logs to be bubbled up to
its parent but not above that. Am i correct?
If yes then setting additivity flag of my common logger wouldn't help(in fact it doesn't :)) and the logs are still printed to both common and root logger. How to prevent this?
#root logger config starts
log4j.rootLogger=INFO, RA
log4j.appender.RA=org.apache.log4j.RollingFileAppender
log4j.appender.RA.File=/Data/var/logs/root.log
log4j.appender.RA.MaxFileSize=100KB
# Keep one backup file
log4j.appender.RA.MaxBackupIndex=1
log4j.appender.RA.layout=org.apache.log4j.PatternLayout
log4j.appender.RA.layout.ConversionPattern=%p %d - %m%n
# root config logger ends
#ico common logger config starts
log4j.logger.com=INFO, COMMONA
log4j.appender.COMMONA=org.apache.log4j.RollingFileAppender
log4j.additivity.com=false
log4j.appender.COMMONA.File=/Data/var/logs/common_ico.log
log4j.appender.COMMONA.MaxFileSize=100KB
# Keep one backup file
log4j.appender.COMMONA.MaxBackupIndex=1
log4j.appender.COMMONA.layout=org.apache.log4j.PatternLayout
log4j.appender.COMMONA.layout.ConversionPattern=[%x]%p %d - %m%n
#ico common logger config ends
Above config works. I was using log4j.additivity.COMMONA=false instead of log4j.additivity.com=false
with this config
<appender name="a2" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="common %m%n" />
</layout>
</appender>
<appender name="a1" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="root %m%n" />
</layout>
</appender>
<logger name="common" additivity="false">
<appender-ref ref="a2" />
</logger>
<root>
<priority value="debug" />
<appender-ref ref="a1" />
</root>
this
Logger.getLogger("common").debug("1111");
prints
common 1111
I've written up a small console utility. Throughout the application, I have used slf4j/log4j to log debug, trace, info statements to the console as I was developing it. Now that I am done development and want to release it, I would like to disable all output to the console except for a couple of specific loggers and send all the remaining loggers to a text file.
In theory, this should be fairly easy. I have created 2 appenders (one ConsoleAppender and one FileAppender). I have assocaited the ConsoleAppender with the specific loggers want on the Console and the FileAppender at the Root level. This works fine.
My issue now, is if I want to completely disable the FileAppender, I cannot figure out how to do it. If I add a DenyAllFilter to the FileAppender, it will prevent anything from being written to the file, but the file is still created. If I remove the FileAppender from the ROOT logger, I get Log4J writting to StdErr:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
If I set the ROOT level to OFF, the individual loggers that I have set custom debug levels to still output.
If I set the LoggerRepository Level to OFF, then all loggers (those I want to go to STDOUT and the File) are all shut off.
Is there any way to do this easily? Ideally, I want to be able to disable the file appender altogether, however provide a command line switch to enable it if desired.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p %c{5} - %X{messageId} - %m%n" />
<!-- <param name="ConversionPattern" value="%m%n" /> -->
</layout>
</appender>
<appender name="LOGTXT" class="org.apache.log4j.FileAppender">
<param name="file" value="lss-client.log" />
<param name="append" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p %c{5} - %X{messageId} - %m%n" />
</layout>
<!-- <filter class="org.apache.log4j.varia.DenyAllFilter"/> -->
</appender>
<!-- Spring Loggers -->
<logger name="org.springframework">
<level value="INFO" />
</logger>
<logger name="org.springframework.ws.client.MessageTracing.sent">
<level value="TRACE" />
</logger>
<logger name="org.springframework.ws.client.MessageTracing.received">
<level value="TRACE" />
</logger>
<logger name="com.cws.cs.Client" >
<level value="INFO" />
<appender-ref ref="STDOUT" />
</logger>
<root>
<level value="INFO" />
<appender-ref ref="LOGTXT" />
</root>
</log4j:configuration>
Thanks!
Eric
Pretty sure Slf4J/Log4J creates the log file immediately when you configure a FileAppender.
I think your best bet here is to have 2 different and complete Log4J configurations and pick which one you load at startup based on your command line parameter.
In PseudoCode:
public static void main(String[] args){
//if log to file arg = true
DOMConfigurator.configure("logToFile.log4j.xml");
//else
DOMConfigurator.configure("logToConsoleOnly.log4j.xml");
}
Edit
Furthermore, if you don't like the idea of maintaining two configuration files. You could create one configuration with the common components (probably the spring stuff and w/e else) and then based on your parameter, programatically configure the FileAppender:
public static void main(String[] args){
DOMConfigurator.configure("log4j.xml");
//if log to file arg = true{
// Define layout
PatternLayout layout = new PatternLayout();
layout.setConversionPattern("%d{ISO8601} %-5p %c{5} - %X{messageId} - %m%n");
// Create appender
FileAppender appender = new FileAppender();
appender.setFile("lss-client.log");
appender.setLayout(layout);
appender.activateOptions();
// Get root logger and add appender.
log = Logger.getRootLogger();
log.setLevel(Level.INFO);
log.addAppender(appender);
}
}
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)));