Skip to content

Commit

Permalink
Log exception stack trace if the last argument is Throwable
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
raccoonback committed Jan 2, 2025
1 parent 96e6824 commit d946148
Showing 1 changed file with 72 additions and 20 deletions.
92 changes: 72 additions & 20 deletions reactor-core/src/main/java/reactor/util/Loggers.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved.
* Copyright (c) 2016-2025 VMware Inc. or its affiliates, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,7 @@

import java.io.PrintStream;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.WeakHashMap;
Expand Down Expand Up @@ -353,7 +354,7 @@ public void trace(String msg) {

@Override
public void trace(String format, Object... arguments) {
logger.log(Level.FINEST, format(format, arguments));
logWithOptionalThrowable(Level.FINEST, format, arguments);
}

@Override
Expand All @@ -373,7 +374,7 @@ public void debug(String msg) {

@Override
public void debug(String format, Object... arguments) {
logger.log(Level.FINE, format(format, arguments));
logWithOptionalThrowable(Level.FINE, format, arguments);
}

@Override
Expand All @@ -393,7 +394,7 @@ public void info(String msg) {

@Override
public void info(String format, Object... arguments) {
logger.log(Level.INFO, format(format, arguments));
logWithOptionalThrowable(Level.INFO, format, arguments);
}

@Override
Expand All @@ -413,7 +414,7 @@ public void warn(String msg) {

@Override
public void warn(String format, Object... arguments) {
logger.log(Level.WARNING, format(format, arguments));
logWithOptionalThrowable(Level.WARNING, format, arguments);
}

@Override
Expand All @@ -433,7 +434,7 @@ public void error(String msg) {

@Override
public void error(String format, Object... arguments) {
logger.log(Level.SEVERE, format(format, arguments));
logWithOptionalThrowable(Level.SEVERE, format, arguments);
}

@Override
Expand All @@ -454,6 +455,24 @@ final String format(@Nullable String from, @Nullable Object... arguments){
}
return null;
}

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));
}

private boolean isLastElementThrowable(Object... arguments) {
int length = arguments.length;
return length > 0 && arguments[length - 1] instanceof Throwable;
}
}

private static class JdkLoggerFactory implements Function<String, Logger> {
Expand Down Expand Up @@ -507,6 +526,39 @@ final String format(@Nullable String from, @Nullable Object... arguments){
return null;
}

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));
}

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));
}

private boolean isLastElementThrowable(Object... arguments) {
int length = arguments.length;
return length > 0 && arguments[length - 1] instanceof Throwable;
}

@Override
public boolean isTraceEnabled() {
return identifier.verbose;
Expand All @@ -521,11 +573,11 @@ public synchronized void trace(String msg) {
}

@Override
public synchronized void trace(String format, Object... arguments) {
public void trace(String format, Object... arguments) {
if (!identifier.verbose) {
return;
}
this.log.format("[TRACE] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
logWithOptionalThrowable("TRACE", format, arguments);
}
@Override
public synchronized void trace(String msg, Throwable t) {
Expand All @@ -550,11 +602,11 @@ public synchronized void debug(String msg) {
}

@Override
public synchronized void debug(String format, Object... arguments) {
public void debug(String format, Object... arguments) {
if (!identifier.verbose) {
return;
}
this.log.format("[DEBUG] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
logWithOptionalThrowable("DEBUG", format, arguments);
}

@Override
Expand All @@ -573,17 +625,17 @@ public boolean isInfoEnabled() {

@Override
public synchronized void info(String msg) {
this.log.format("[ INFO] (%s) %s\n", Thread.currentThread().getName(), msg);
this.log.format("[INFO] (%s) %s\n", Thread.currentThread().getName(), msg);
}

@Override
public synchronized void info(String format, Object... arguments) {
this.log.format("[ INFO] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
public void info(String format, Object... arguments) {
logWithOptionalThrowable("INFO", format, arguments);
}

@Override
public synchronized void info(String msg, Throwable t) {
this.log.format("[ INFO] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
this.log.format("[INFO] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
t.printStackTrace(this.log);
}

Expand All @@ -594,17 +646,17 @@ public boolean isWarnEnabled() {

@Override
public synchronized void warn(String msg) {
this.err.format("[ WARN] (%s) %s\n", Thread.currentThread().getName(), msg);
this.err.format("[WARN] (%s) %s\n", Thread.currentThread().getName(), msg);
}

@Override
public synchronized void warn(String format, Object... arguments) {
this.err.format("[ WARN] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
public void warn(String format, Object... arguments) {
logErrorWithOptionalThrowable("WARN", format, arguments);
}

@Override
public synchronized void warn(String msg, Throwable t) {
this.err.format("[ WARN] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
this.err.format("[WARN] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
t.printStackTrace(this.err);
}

Expand All @@ -619,8 +671,8 @@ public synchronized void error(String msg) {
}

@Override
public synchronized void error(String format, Object... arguments) {
this.err.format("[ERROR] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
public void error(String format, Object... arguments) {
logErrorWithOptionalThrowable("ERROR", format, arguments);
}

@Override
Expand Down

0 comments on commit d946148

Please sign in to comment.