-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support logging exception stack traces when the last argument is Throwable #3960
base: main
Are you sure you want to change the base?
Conversation
- Enhanced logger methods to check if the last argument is of type Throwable. - If Throwable is detected, its stack trace is included in the log output. - Improves debugging by seamlessly handling exception logging alongside message formatting. ref. https://www.slf4j.org/faq.html#paramException
e336792
to
d946148
Compare
private boolean isLastElementThrowable(Object... arguments) { | ||
int length = arguments.length; | ||
return length > 0 && arguments[length - 1] instanceof Throwable; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checks whether the last argements are of type Throwable
.
private void logWithOptionalThrowable(Level level, String format, Object... arguments) { | ||
if(isLastElementThrowable(arguments)) { | ||
int lastIndex = arguments.length - 1; | ||
Object[] args = Arrays.copyOfRange(arguments, 0, lastIndex); | ||
Throwable t = (Throwable) arguments[lastIndex]; | ||
|
||
logger.log(level, format(format, args), t); | ||
return; | ||
} | ||
|
||
logger.log(level, format(format, arguments)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In JdkLogger
, if the last arguments are Throwable
type, stacktrace is also logged.
private boolean isLastElementThrowable(Object... arguments) { | ||
int length = arguments.length; | ||
return length > 0 && arguments[length - 1] instanceof Throwable; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checks whether the last argements are of type Throwable
.
private synchronized void logWithOptionalThrowable(String level, String format, Object... arguments) { | ||
if(isLastElementThrowable(arguments)) { | ||
int lastIndex = arguments.length - 1; | ||
Object[] args = Arrays.copyOfRange(arguments, 0, lastIndex); | ||
Throwable t = (Throwable) arguments[lastIndex]; | ||
|
||
this.log.format("[%s] (%s) %s\n", level.toUpperCase(), Thread.currentThread().getName(), format(format, args)); | ||
t.printStackTrace(this.log); | ||
return; | ||
} | ||
|
||
this.log.format("[%s] (%s) %s\n", level.toUpperCase(), Thread.currentThread().getName(), format(format, arguments)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In ConsoleLogger
, if the last argument is of type Throwable
, it also prints a stack trace.
(only use for TRACE, DEBUG, INFO level)
private synchronized void logErrorWithOptionalThrowable(String level, String format, Object... arguments) { | ||
if(isLastElementThrowable(arguments)) { | ||
int lastIndex = arguments.length - 1; | ||
Object[] args = Arrays.copyOfRange(arguments, 0, lastIndex); | ||
Throwable t = (Throwable) arguments[lastIndex]; | ||
|
||
this.err.format("[%s] (%s) %s\n", level.toUpperCase(), Thread.currentThread().getName(), format(format, args)); | ||
t.printStackTrace(this.err); | ||
return; | ||
} | ||
|
||
this.err.format("[%s] (%s) %s\n", level.toUpperCase(), Thread.currentThread().getName(), format(format, arguments)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In ConsoleLogger
, if the last arguments are Throwable
type, it also prints a stack trace with the err
PrintStream.
(only use for WARN, ERROR level)
Motivation
Hello,
Reactor Core supports SLF4J, Console Logger, and JDK Logger.
In SLF4J implementations (e.g., Logback), when the last argument is of type Throwable, the exception stack trace is automatically logged, as shown below.
(ref. SLF4J FAQ)
(ref: Logback implementation)
However, the Console Logger and JDK Logger supported by Reactor Core do not provide this functionality, and users must manually check for
Throwable
and handle it accordingly in their code.This results in unnecessary branching in user code and decreases consistency across logging mechanisms.
Therefore, in this change, we have modified the
ConsoleLogger
andJdkLogger
to detect if the last argument is of typeThrowable
and automatically log the exception stack trace.Description
This PR enhances the logging functionality in Reactor Core to check if the last argument in logger methods is of type
Throwable
. If aThrowable
is detected, the exception stack trace is included in the log output.Key Changes
Throwable
instances for improved debugging.Example Usage
Before
After
Benefits
Testing