I have created a java project called Project1. for this project i created a log4j.properties file. For writing the log statements in log file, i used DailyRollingFileAppenders. I am using log4j-1.2.16.jar. The log file is :
log4j.logger.com.gridsense.server.automode=DEBUG, stdout,Rollfile
log4j.rootLogger=off
log4j.logger.com.gridsense.server.automode=debug,Rollfile,stdout
log4j.appender.Rollfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Rollfile.ImmediateFlush=false
log4j.appender.Rollfile.Append=true
log4j.appender.Rollfile.Threshold=DEBUG
log4j.appender.Rollfile.bufferedIO = true
log4j.appender.Rollfile.File=D:/logs/AutoGS.log
log4j.appender.Rollfile.layout=org.apache.log4j.PatternLayout
log4j.appender.Rollfile.layout.ConversionPattern=[%t] %-5p %c %d{dd/MM/yyyy HH:mm:ss} %m%n
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=DEBUG
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x %m%n
When i run the project i get the following error
log4j:ERROR Could not close org.apache.log4j.helpers.QuietWriter#1105348
java.io.IOException: The handle is invalid
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:282)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:263)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:106)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
at java.io.BufferedWriter.close(BufferedWriter.java:246)
at java.io.FilterWriter.close(FilterWriter.java:87)
at org.apache.log4j.FileAppender.closeFile(FileAppender.java:185)
at org.apache.log4j.FileAppender.reset(FileAppender.java:343)
at org.apache.log4j.WriterAppender.close(WriterAppender.java:207)
at org.apache.log4j.AppenderSkeleton.finalize(AppenderSkeleton.java:144)
at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
log4j:ERROR Failed to write [[DefaultQuartzScheduler_Worker-2] DEBUG com.gridsense.server.automode.backgroundWorker.TimerTaskToBeFired 03/05/2013 17:34:45 ? TimerTaskToBeFired.execute - firing timer job with Key [DropBoxFileFetchingSchedulerGroup.JobDetail-ID-1]].
I don't understand what is the problem.
My reading of the stacktrace is that something has leaked a FileAppender object, and that appender's finalize method is attempting to clean it up. But it looks like that is failing because the resource in question has already been closed.
That's the easy part. The hard part is identifying the source of the leak. My guess is that it is caused by this line:
log4j.logger.com.gridsense.server.automode=debug,Rollfile,stdout
which appears to be configuring a second logger tree duplicating the one configure a couple of lines earlier.
Related
I am trying to get a custom throwableRenderer to work with log4j 1.2.17.
Note that I cannot upgrade to log4j2 at this stage so I am looking for 1.x solution.
See e.g.
How to make log4j syslog appender write a stack trace in one line?
I am trying to do just that - get the stack trace to be printed on 1 line. I tried 2 approaches I could find on the web - using custom renderer and using Enhanced Pattern Layout. Still no luck!
But the class WRThrowableRenderer (which is my custom renderer)
and its method doRender is simply not called.
This is all in a web app running inside WildFly 8 (Java 8).
I tried at least 10 different things while testing the two approaches but nothing works.
What am I doing wrong?!
Also, is this renderer supposed to affect all loggers and change their behavior when an exception is logged? I think so. I am asking this because I have child loggers under this rootLogger. And they all log via the rootLogger in one single file.
log4j.rootLogger=INFO, stdout
log4j.throwableRenderer=com.yb.common.logging.WRThrowableRenderer
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
# log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}:%L### - [[[%m]]]%n
# log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]]%n %throwable{separator(|)}
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]]%n
# log4j.appender.stdout.layout.ConversionPattern=%m%n
log4j.appender.stdout.threshold=INFO
log4j.appender.stdout.immediateFlush=true
I am trying to do just that - get the stack trace to be printed on 1 line. I tried 2 approaches I could find on the web - using custom renderer and using Enhanced Pattern Layout.
Without a custom ThrowableRenderer
If you want the stack trace all on one line without using a custom ThrowableRenderer, the best you'll be able to do is get the first line of the stack trace.
For example, using this configuration:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d] %-5p %m %throwable{short}%n
Will generate this log:
[2020-11-20 10:54:53,454] ERROR Test error message, with stack trace java.lang.IllegalArgumentException: Test exception message
With a custom ThrowableRenderer
If you want the entire stack trace printed on one line, you'll need to use a custom ThrowableRenderer.
Create the custom ThrowableRenderer, e.g.
package org.example;
import org.apache.log4j.DefaultThrowableRenderer;
import org.apache.log4j.spi.ThrowableRenderer;
import java.util.ArrayList;
import java.util.Arrays;
public class CustomThrowableRenderer implements ThrowableRenderer {
private final DefaultThrowableRenderer defaultRenderer = new DefaultThrowableRenderer();
#Override
public String[] doRender(Throwable throwable) {
String[] defaultRepresentation = defaultRenderer.doRender(throwable);
String[] newRepresentation = {String.join("|", Arrays.asList(defaultRepresentation))};
return newRepresentation;
}
}
Configure log4j1 to use the custom ThrowableRenderer
log4j.throwableRenderer=org.example.CustomThrowableRenderer
At this point, the stack trace portion of the log will all be on one line, although it may be on a separate line from the rest of the log.
For example, your configuration from above:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]]%n
log4j.throwableRenderer=org.example.CustomThrowableRenderer
Will generate two lines because the stack trace is put on its own line by default:
2020-11-20 11:45:04.706 ERROR [main] ###org.example.App### [[[Test error message, with stack trace]]]
java.lang.IllegalArgumentException: Test exception message| at org.example.App.logErrorWithStackTrace(App.java:31)| at org.example.App.okayThatsEnough(App.java:25)| at org.example.App.notLongEnough(App.java:21)| at org.example.App.makeStackTraceLonger(App.java:17)| at org.example.App.testLoggingWithStackTraces(App.java:13)| at org.example.App.main(App.java:9)
You can get the error message and stack trace on one line by using %throwable in your pattern:
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] ###%c{20}### [[[%m]]] %throwable%n
However a blank line will be generated after:
2020-11-20 11:46:46.897 ERROR [main] ###org.example.App### [[[Test error message, with stack trace]]] java.lang.IllegalArgumentException: Test exception message| at org.example.App.logErrorWithStackTrace(App.java:31)| at org.example.App.okayThatsEnough(App.java:25)| at org.example.App.notLongEnough(App.java:21)| at org.example.App.makeStackTraceLonger(App.java:17)| at org.example.App.testLoggingWithStackTraces(App.java:13)| at org.example.App.main(App.java:9)
That could probably be fixed as well but it might require a custom appender.
I made a small sample app you can use as a reference: https://github.com/bmaupin/junkpile/tree/master/java/log4j1-custom-throwablerenderer
I have been trying to log messages from a specific class. I only want the specific messages from that class to log to a separate file and nothing else. I cant seem to get it right and I have tried multiple configurations including XML format. Id be helpful for feedback on my configuration. (see Below )
log4j2.appender.solrindexlog.type=RollingFile
log4j2.appender.solrindexlog.name=SolrIndexLog
log4j2.appender.solrindexlog.fileName=${NAME_LOG_DIR}/tomcat/solrindex.log
log4j2.appender.solrindexlog.filePattern=${NAME_LOG_DIR}/tomcat/solrindexlog-%d{yyyyMMdd}.log
log4j2.appender.solrindexlog.layout.type=PatternLayout
log4j2.appender.solrindexlog.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
log4j2.appender.solrindexlog.policies.type=Policies
log4j2.appender.solrindexlog.policies.time.type=TimeBasedTriggeringPolicy
log4j2.appender.solrindexlog.policies.time.interval=2
log4j2.appender.solrindexlog.policies.time.modulate=true
log4j2.appender.solrindexlog.policies.size.type=SizeBasedTriggeringPolicy
log4j2.appender.solrindexlog.policies.size.size=100MB
log4j2.appender.solrindexlog.strategy.type=DefaultRolloverStrategy
log4j2.appender.solrindexlog.strategy.max=5
log4j2.logger.solrindexlog.name=se.package.name
log4j2.logger.solrindexlog.level=debug
log4j2.logger.solrindexlog.appenderRefs=stdout
log4j2.logger.solrindexlog.appenderRef.stdout.ref=STDOUT
log4j2.rootLogger.level=info
log4j2.rootLogger.appenderRef.stdout.ref=STDOUT
log4j2.rootLogger.appenderRef.solrindexlog.ref=SolrIndexLog
log4j2.rootLogger.appenderRefs=stdout,solrindexlog
Try below configuration file -
appender.solrindexlog.type=RollingFile
appender.solrindexlog.name=SolrIndexLog
appender.solrindexlog.fileName=${NAME_LOG_DIR}/tomcat/solrindex.log
appender.solrindexlog.filePattern=${NAME_LOG_DIR}/tomcat/solrindexlog-%d{yyyyMMdd}.log
appender.solrindexlog.layout.type=PatternLayout
appender.solrindexlog.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
appender.solrindexlog.policies.type=Policies
appender.solrindexlog.policies.time.type=TimeBasedTriggeringPolicy
appender.solrindexlog.policies.time.interval=2
appender.solrindexlog.policies.time.modulate=true
appender.solrindexlog.policies.size.type=SizeBasedTriggeringPolicy
appender.solrindexlog.policies.size.size=100MB
appender.solrindexlog.strategy.type=DefaultRolloverStrategy
appender.solrindexlog.strategy.max=5
logger.se.package.name.name=se.package.name
logger.se.package.name.level=debug
logger.se.package.name.additivity = false
logger.se.package.name.appenderRef.solrindexlog.ref= SolrIndexLog
logger.se.package.name.appenderRef.stdout.ref= STDOUT
rootLogger.level=info
rootLogger.additivity = false
rootLogger.appenderRef.solrindexlog.ref= SolrIndexLog
rootLogger.appenderRef.stdout.ref= STDOUT
Please change other parts of the configuration file that are not written in above configuration file like ConsoleAppender etc.
Also, as per this configuration file, all logs message will go in file as well as in console.
I am new to the Log4j framework and after reading some stuff i got some fare idea about logging mechanism, but still
i have some doubt about the following properties.
log4j.category.com.cloud.sample=INFO, file, C
log4j.additivity.com.cloud.sample=true
log4j.appender.C=org.apache.log4j.ConsoleAppender
log4j.appender.C.Target=System.out
log4j.appender.C.ImmediateFlush=true
log4j.appender.C.layout=org.apache.log4j.PatternLayout
log4j.appender.C.layout.ConversionPattern=%-5p %d [%t] %m%n
#log4j.rootLogger=INFO, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
### direct messages to file ###
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=${catalina.home}/var/basic/logs/sample.log
log4j.appender.file.Append=true
log4j.appender.file.MaxFileSize=10MB
# mylog.log.10 \u307e\u3067\u4fdd\u6301
log4j.appender.file.MaxBackupIndex=50
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %5p [%t] %c{1} - %m%n
log4j.rootLogger=INFO, C, file
In the first line of the above code contains two appenders(file, C) after that we will be having appender for both file and C. So as per my understanding logs will of category will be stored to Console and sample.log. Please let me know if i am wrong.
log4j.rootLogger=INFO, A1 and respective properties are not used right?
log4j.rootLogger=INFO, C, file: This line is about root logger, I think in my case it is not useful, because it is defined at the last line and there is no properties defined over here.
Please could any body confirm my understanding and suggest me if any changes required in the above configuration
The root logger resides at the top of the logger hierarchy. It is exceptional in three ways:
it always exists,
its level cannot be set to null
it cannot be retrieved by name.
The rootLogger is the father of all appenders. Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy (including rootLogger).
I've seen many questions concerning log4j not writing any files, but my problem is that, log4j does (seem to) work, but not for all files.
My configuration is as follows (I have omitted a few loggers for simplicity, the below lines appear in the order they are in in the file):
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 %5p %c{1}:%L - %m%n
# this logger works without any problems
log4j.appender.errorFile=org.apache.log4j.RollingFileAppender
log4j.appender.errorFile.File=${LOG_HOME}/errors.log
log4j.appender.errorFile.MaxFileSize=20MB
log4j.appender.errorFile.MaxBackupIndex=10
log4j.appender.errorFile.layout=org.apache.log4j.PatternLayout
log4j.appender.errorFile.layout.ConversionPattern=%d %5p %c{1}:%L - %m%n
log4j.appender.errorFile.Threshold=ERROR
# this file is created but always empty
log4j.appender.barcodeScanner=org.apache.log4j.RollingFileAppender
log4j.appender.barcodeScanner.File=${LOG_HOME}/barcodeScanner.log
log4j.appender.barcodeScanner.MaxFileSize=20MB
log4j.appender.barcodeScanner.MaxBackupIndex=5
log4j.appender.barcodeScanner.layout=org.apache.log4j.PatternLayout
log4j.appender.barcodeScanner.layout.ConversionPattern=%d %5p %c{1}:%L - %m%n
# this logger also works
log4j.appender.DoubleDtpaList=org.apache.log4j.RollingFileAppender
log4j.appender.DoubleDtpaList.File=${LOG_HOME}/DoubleDtpaList.log
log4j.appender.DoubleDtpaList.MaxFileSize=20MB
log4j.appender.DoubleDtpaList.MaxBackupIndex=1
log4j.appender.DoubleDtpaList.layout=org.apache.log4j.PatternLayout
log4j.appender.DoubleDtpaList.layout.ConversionPattern=%d %5p %c{1}:%L - %m%n
log4j.rootLogger=error, errorFile
log4j.logger.scanner.BarcodeScanner=debug, barcodeScanner
log4j.logger.util.DetectDoubles=trace, DoubleDtpaList
Using the logger within the BarcodeScanner class yields correct results when using logger.error() (this logs to the errors.log file), but all calls to logger.debug() and logger.info() have no effect.
The variable LOG_HOME is passed as an argument/option when executing the *.jar file.
EDIT 1: I added another (working) logger/appender configuration for clarification. Another piece of information I unfortunately left out ist that I want all logs for the scanner to go to the barcodeScanner.log file (with the errors additionally going to errors.log (root Logger)
I am adding logging to a java web project I am working on. I have run into an error that I am unable to figure out.
The error I am getting from tomcat is:
log4j:ERROR Could not read configuration file [log4j.properties].
java.io.FileNotFoundException: log4j.properties (No such file or directory)
I have this simple method in my class:
#RemotingInclude
public UserAccount save(UserAccount dataObject)
{
PropertyConfigurator.configure("log4j.properties");
logger.debug(dataObject.toString());
return dao.save(dataObject);
}
When I look in my webapps//WEB-INF/class folder I do see my log4j.properties file. When I deploy to my tomcat server and restart tomcat, I do see my admin.log file created, but nothing is written to it. Even after hitting the method above. Any help with this is greatly appreciated.
This is the current contents of my log4j.properties file:
log4j.appender.AdminFileAppender=org.apache.log4j.FileAppender
log4j.appender.AdminFileAppender.File=admin.log
log4j.appender.AdminFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.AdminFileAppender.layout.ConversionPattern= %-4r [%t] %-5p %c %x - %m%n.
log4j.appender.ReportFileAppender=org.apache.log4j.FileAppender
log4j.appender.ReportFileAppender.File=report.log
log4j.appender.ReportFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.ReportFileAppender.layout.ConversionPattern= %-4r [%t] %-5p %c %x - %m%n
log4j.logger.com.rottmanj.services=WARN,AdminFileAppender
That approach of bootstraping the Log4j is wrong. This is usually the way that is implemented:
import org.apache.log4j.Logger;
public class MyService {
public UserAccount save(UserAccount dataObject) {
logger.debug(dataObject.toString());
return dao.save(dataObject);
}
private static Logger logger = Logger.getLogger(MyService.class);
}
This way Log4j will automatically lookup for the log4j.properties in the root of the classpath.