You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Robert Pepersack <RP...@mdinsurance.state.md.us> on 2008/04/23 22:19:11 UTC
FileAppender Truncates Stack Trace
Hello,
I'm using FileAppender to log to a log file. When an exception gets caught and printed, the stack trace is truncated as it usually is by default:
Caused by: com.sybase.jdbc3.jdbc.SybSQLException: Attempt to insert NULL value into column 'id', table 'table'; column does not allow nulls. Update fails.
at com.sybase.jdbc3.tds.Tds.a(Unknown Source)
at com.sybase.jdbc3.tds.Tds.nextResult(Unknown Source)
at com.sybase.jdbc3.jdbc.ResultGetter.nextResult(Unknown Source)
at com.sybase.jdbc3.jdbc.SybStatement.nextResult(Unknown Source)
at com.sybase.jdbc3.jdbc.SybStatement.nextResult(Unknown Source)
at com.sybase.jdbc3.jdbc.SybStatement.queryLoop(Unknown Source)
at com.sybase.jdbc3.jdbc.SybCallableStatement.executeQuery(Unknown Source)
at miaJs.jdbc.JdbcFacade.executeQuery(JdbcFacade.java:977)
... 14 more
Instead of the "... 14 more" at the bottom, I would like to see the entire stack trace. I know how to get Java to do this by using Throwable.getStackTrace(), and then loop through the array of StackTraceElements. I looked in the log4j source code. I think that FileAppender uses the OnlyOnceErrorHandler in its super, superclass AppenderSkeleton. It looks like OnlyOnceErrorHandler uses LogLog. But, I'm not sure how to get log4j to print the entire stack trace.
Thanks,
Bob
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: FileAppender Truncates Stack Trace
Posted by Curt Arnold <ca...@apache.org>.
On Apr 24, 2008, at 8:04 AM, Robert Pepersack wrote:
> Thanks for your reply.
>
> I've seen this behavior with many different exception classes, so I
> think it's the VM.
>
> I've written a couple of appenders before. For example, I wrote a
> SystemOutAppender that solves this problem when printing to the
> console. The source code for SystemOutAppender is below. How would
> I adapt this to work as DailyRollingFileAppender and FileAppender?
>
As I mentioned in my original post, the right place to address this is
in the Layout. Something like:
package com.example.logging;
public class PatternLayout extends org.apache.log4j.PatternLayout {
public PatternLayout() {
}
public String format(final LoggingEvent event) {
String msg = super.format(event);
ThrowableInformation throwInfo =
event.getThrowableInformation();
if (throwInfo == null) {
return msg;
} else {
StringBuffer buf = new StringBuffer(msg);
buf.append(Layout.LINE_SEP);
Throwable throwable = throwInfo.getThrowable();
//
// deserialized LoggingEvents would be missing
throwable
// so just output their previously captured
stack trace
if (throwable == null) {
String[] rendered =
throwInfo.getThrowableStrRep();
for(int i = 0; i < rendered.length; i++) {
buf.append(rendered[i]);
buf.append(Layout.LINE_SEP);
}
} else {
//
// your stack trace code goes here
//
}
return buf.toString();
}
}
public boolean ignoresThrowable() {
return false;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: FileAppender Truncates Stack Trace
Posted by Robert Pepersack <RP...@mdinsurance.state.md.us>.
Thanks for your reply.
I've seen this behavior with many different exception classes, so I think it's the VM.
I've written a couple of appenders before. For example, I wrote a SystemOutAppender that solves this problem when printing to the console. The source code for SystemOutAppender is below. How would I adapt this to work as DailyRollingFileAppender and FileAppender?
// SystemOutAppender.java
package myapp;
import org.apache.log4j.Layout;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.log4j.AppenderSkeleton;
/**
* SystemOutAppender is a custom log4j appender
* that writes to the console using System.out.
* Its output includes nested exceptions and their
* stack traces.
*/
public class SystemOutAppender extends AppenderSkeleton
{
/**
* Default constructor.
*/
public SystemOutAppender(){}
/**
* Construct an appender with the specified
* Layout.
*/
public SystemOutAppender(Layout layout)
{
this.layout = layout;
}
/**
* Implement the abstract append method
* inherited from AppenderSkeleton, which
* AppenderSkeleton calls from doAppend().
*/
public void append(LoggingEvent event)
{
ThrowableInformation throwableInfo = null;
Throwable throwable = null;
Throwable cause = null;
String exceptionId = null;
StackTraceElement[] stackTrace = null;
String smallIndent = " ";
String largeIndent = " at ";
StringBuffer stringBuffer = new StringBuffer();
// Print the information indicated by the
// Layout.
stringBuffer.append(this.layout.format(event));
// Check to see if this LoggingEvent has
// ThrowableInformation.
if ((throwableInfo = event.getThrowableInformation()) != null)
{
// Check to see if there is a Throwable.
// If there is a Throwable, check to see
// if it is RuntimeApplicationException. If
// so, then get its exception ID.
if ((throwable = throwableInfo.getThrowable()) != null)
{
cause = throwable;
// Drill down to the point where there is
// no cause encapsulated by the current
// cause.
while(cause != null)
{
stringBuffer.append(smallIndent);
// "Caused by: " is unnecessary for the
// outermost Throwable.
if (cause != throwable)
{
stringBuffer.append("Caused by: ");
}
stringBuffer.append(cause.toString() + "\n");
// Get the StackTraceElements for this cause.
stackTrace = cause.getStackTrace();
// Loop through all of the StackTraceElements
// for this cause and append them to the
// StringBuffer.
for(int i = 0; i < stackTrace.length; i++)
{
stringBuffer.append(largeIndent +
stackTrace[i] +
"\n");
}
cause = cause.getCause();
}
}
}
// Print the contents of the StringBuffer.
System.out.println(stringBuffer.toString());
}
public boolean requiresLayout()
{
return true;
}
public void close()
{
if (this.closed)
{
return;
}
this.closed = true;
}
}
Thanks,
Bob
>>> Curt Arnold <ca...@apache.org> 04/23/2008 6:19 PM >>>
Okay, I'm assuming that somewhere this exception is passed to log4j in
something like:
try {
///
} catch(Exception ex) {
logger.info("Some app message", ex);
}
Using a standard layout, the stack trace will get rendered by
WriterAppender.subAppend.
this.qw.write(this.layout.format(event));
if(layout.ignoresThrowable()) {
String[] s = event.getThrowableStrRep();
if (s != null) {
int len = s.length;
for(int i = 0; i < len; i++) {
this.qw.write(s[i]);
this.qw.write(Layout.LINE_SEP);
}
}
}
Most appenders will return ignoreThrowable to true which will result
in org.apache.log4j.spi.LoggingEvent;getThrowableStrRep() to render
the exception which will eventually end up at
org.apache.log4j.spi.ThrowableInformation.getThrowableStrRep() which
will then call the printStackTrace() method of the exception. The
SymSQLException.printStackTrace() implementation (or the underlying
JVM) is most likely the source of the ".. 14 more".
At least as I understand the situation, OnlyOnceErrorHandler would not
be involved. It would only be involved if the appender was raising
exceptions and you mentioned using a FileAppender and a file appender
should not be raising SQL exceptions.
A custom object renderer would not be useful unless the exception was
used as the message parameter, which is probably not the case.
The best way to add a custom rendering of the stack trace would be to
write a custom appender (likely either wrapping or extending
PatternLayout) which returns false ignoresThrowable() and then appends
your custom equivalent to printStackTrace() the the result of the
PatternLayout.format.
On Apr 23, 2008, at 3:28 PM, Matthew Kemp wrote:
> You can create your own custom object renderer that will properly
> render the
> whole stack trace. This renderer will need to be included in the log4j
> config and be available on the classpath when log4j initializes.
>
>
> On Wed, Apr 23, 2008 at 3:19 PM, Robert Pepersack <
> RPepersack@mdinsurance.state.md.us> wrote:
>
>> Hello,
>>
>> I'm using FileAppender to log to a log file. When an exception gets
>> caught and printed, the stack trace is truncated as it usually is by
>> default:
>>
>> Caused by: com.sybase.jdbc3.jdbc.SybSQLException: Attempt to insert
>> NULL
>> value into column 'id', table 'table'; column does not allow nulls.
>> Update
>> fails.
>>
>> at com.sybase.jdbc3.tds.Tds.a(Unknown Source)
>> at com.sybase.jdbc3.tds.Tds.nextResult(Unknown Source)
>> at com.sybase.jdbc3.jdbc.ResultGetter.nextResult(Unknown
>> Source)
>> at com.sybase.jdbc3.jdbc.SybStatement.nextResult(Unknown
>> Source)
>> at com.sybase.jdbc3.jdbc.SybStatement.nextResult(Unknown
>> Source)
>> at com.sybase.jdbc3.jdbc.SybStatement.queryLoop(Unknown Source)
>> at
>> com.sybase.jdbc3.jdbc.SybCallableStatement.executeQuery(Unknown
>> Source)
>> at miaJs.jdbc.JdbcFacade.executeQuery(JdbcFacade.java:977)
>> ... 14 more
>>
>> Instead of the "... 14 more" at the bottom, I would like to see the
>> entire stack trace. I know how to get Java to do this by using
>> Throwable.getStackTrace(), and then loop through the array of
>> StackTraceElements. I looked in the log4j source code. I think that
>> FileAppender uses the OnlyOnceErrorHandler in its super, superclass
>> AppenderSkeleton. It looks like OnlyOnceErrorHandler uses LogLog.
>> But, I'm
>> not sure how to get log4j to print the entire stack trace.
>>
>> Thanks,
>>
>> Bob
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
>> For additional commands, e-mail: log4j-user-help@logging.apache.org
>>
>>
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: FileAppender Truncates Stack Trace
Posted by Curt Arnold <ca...@apache.org>.
On Apr 23, 2008, at 5:19 PM, Curt Arnold wrote:
>
> The best way to add a custom rendering of the stack trace would be
> to write a custom appender (likely either wrapping or extending
> PatternLayout) which returns false ignoresThrowable() and then
> appends your custom equivalent to printStackTrace() the the result
> of the PatternLayout.format.
Corrections in CAPS:
The best way to add a custom rendering of the stack trace would be to
write a custom appender (likely either wrapping or extending
PatternLayout) which returns false FOR ignoresThrowable() and then
appends your custom equivalent OF printStackTrace() TO the the result
of the PatternLayout.format.
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: FileAppender Truncates Stack Trace
Posted by Curt Arnold <ca...@apache.org>.
Okay, I'm assuming that somewhere this exception is passed to log4j in
something like:
try {
///
} catch(Exception ex) {
logger.info("Some app message", ex);
}
Using a standard layout, the stack trace will get rendered by
WriterAppender.subAppend.
this.qw.write(this.layout.format(event));
if(layout.ignoresThrowable()) {
String[] s = event.getThrowableStrRep();
if (s != null) {
int len = s.length;
for(int i = 0; i < len; i++) {
this.qw.write(s[i]);
this.qw.write(Layout.LINE_SEP);
}
}
}
Most appenders will return ignoreThrowable to true which will result
in org.apache.log4j.spi.LoggingEvent;getThrowableStrRep() to render
the exception which will eventually end up at
org.apache.log4j.spi.ThrowableInformation.getThrowableStrRep() which
will then call the printStackTrace() method of the exception. The
SymSQLException.printStackTrace() implementation (or the underlying
JVM) is most likely the source of the ".. 14 more".
At least as I understand the situation, OnlyOnceErrorHandler would not
be involved. It would only be involved if the appender was raising
exceptions and you mentioned using a FileAppender and a file appender
should not be raising SQL exceptions.
A custom object renderer would not be useful unless the exception was
used as the message parameter, which is probably not the case.
The best way to add a custom rendering of the stack trace would be to
write a custom appender (likely either wrapping or extending
PatternLayout) which returns false ignoresThrowable() and then appends
your custom equivalent to printStackTrace() the the result of the
PatternLayout.format.
On Apr 23, 2008, at 3:28 PM, Matthew Kemp wrote:
> You can create your own custom object renderer that will properly
> render the
> whole stack trace. This renderer will need to be included in the log4j
> config and be available on the classpath when log4j initializes.
>
>
> On Wed, Apr 23, 2008 at 3:19 PM, Robert Pepersack <
> RPepersack@mdinsurance.state.md.us> wrote:
>
>> Hello,
>>
>> I'm using FileAppender to log to a log file. When an exception gets
>> caught and printed, the stack trace is truncated as it usually is by
>> default:
>>
>> Caused by: com.sybase.jdbc3.jdbc.SybSQLException: Attempt to insert
>> NULL
>> value into column 'id', table 'table'; column does not allow nulls.
>> Update
>> fails.
>>
>> at com.sybase.jdbc3.tds.Tds.a(Unknown Source)
>> at com.sybase.jdbc3.tds.Tds.nextResult(Unknown Source)
>> at com.sybase.jdbc3.jdbc.ResultGetter.nextResult(Unknown
>> Source)
>> at com.sybase.jdbc3.jdbc.SybStatement.nextResult(Unknown
>> Source)
>> at com.sybase.jdbc3.jdbc.SybStatement.nextResult(Unknown
>> Source)
>> at com.sybase.jdbc3.jdbc.SybStatement.queryLoop(Unknown Source)
>> at
>> com.sybase.jdbc3.jdbc.SybCallableStatement.executeQuery(Unknown
>> Source)
>> at miaJs.jdbc.JdbcFacade.executeQuery(JdbcFacade.java:977)
>> ... 14 more
>>
>> Instead of the "... 14 more" at the bottom, I would like to see the
>> entire stack trace. I know how to get Java to do this by using
>> Throwable.getStackTrace(), and then loop through the array of
>> StackTraceElements. I looked in the log4j source code. I think that
>> FileAppender uses the OnlyOnceErrorHandler in its super, superclass
>> AppenderSkeleton. It looks like OnlyOnceErrorHandler uses LogLog.
>> But, I'm
>> not sure how to get log4j to print the entire stack trace.
>>
>> Thanks,
>>
>> Bob
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
>> For additional commands, e-mail: log4j-user-help@logging.apache.org
>>
>>
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: FileAppender Truncates Stack Trace
Posted by Matthew Kemp <ma...@gmail.com>.
You can create your own custom object renderer that will properly render the
whole stack trace. This renderer will need to be included in the log4j
config and be available on the classpath when log4j initializes.
On Wed, Apr 23, 2008 at 3:19 PM, Robert Pepersack <
RPepersack@mdinsurance.state.md.us> wrote:
> Hello,
>
> I'm using FileAppender to log to a log file. When an exception gets
> caught and printed, the stack trace is truncated as it usually is by
> default:
>
> Caused by: com.sybase.jdbc3.jdbc.SybSQLException: Attempt to insert NULL
> value into column 'id', table 'table'; column does not allow nulls. Update
> fails.
>
> at com.sybase.jdbc3.tds.Tds.a(Unknown Source)
> at com.sybase.jdbc3.tds.Tds.nextResult(Unknown Source)
> at com.sybase.jdbc3.jdbc.ResultGetter.nextResult(Unknown Source)
> at com.sybase.jdbc3.jdbc.SybStatement.nextResult(Unknown Source)
> at com.sybase.jdbc3.jdbc.SybStatement.nextResult(Unknown Source)
> at com.sybase.jdbc3.jdbc.SybStatement.queryLoop(Unknown Source)
> at com.sybase.jdbc3.jdbc.SybCallableStatement.executeQuery(Unknown
> Source)
> at miaJs.jdbc.JdbcFacade.executeQuery(JdbcFacade.java:977)
> ... 14 more
>
> Instead of the "... 14 more" at the bottom, I would like to see the
> entire stack trace. I know how to get Java to do this by using
> Throwable.getStackTrace(), and then loop through the array of
> StackTraceElements. I looked in the log4j source code. I think that
> FileAppender uses the OnlyOnceErrorHandler in its super, superclass
> AppenderSkeleton. It looks like OnlyOnceErrorHandler uses LogLog. But, I'm
> not sure how to get log4j to print the entire stack trace.
>
> Thanks,
>
> Bob
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
>
>