Add Throwable parameter to all methods on Log.Logger interface

This is a breaking change, but the alternatives seem either equally
breaking or worse, since the only way to make this non-breaking is
to add the `Throwable` overloads as `default` methods. It's then
unclear how we would ever migrate to these being the 'only' methods
or whether we'd have to keep both forms forever (which results in
duplication in the `Logger` implementations).

The clean break here also makes it clear that the `message` parameter
of `Log.Logger.{d,i,w,w}()` no longer automatically includes any info
from the `Throwable` passed to the static `Log.{d,i,w,e}() methods.

----

This CL also cleans up the javadoc on the static `Log.{d,w,i,e}` methods
since they no longer necessarily call straight through to the
corresponding `android.util.Log` methods (and haven't since <unknown commit>
and Issue: google/ExoPlayer#10185).

PiperOrigin-RevId: 537817974
This commit is contained in:
ibaker 2023-06-05 09:55:10 +00:00 committed by Tofunmi Adigun-Hameed
parent 997f2be5e5
commit 3cb6fe9fcf
2 changed files with 96 additions and 37 deletions

View File

@ -3,6 +3,12 @@
### Unreleased changes ### Unreleased changes
* Common Library: * Common Library:
* Add a `@Nullable Throwable` parameter to the methods in the `Log.Logger`
interface. The `message` parameter to these methods no longer contains
any information about the `Throwable` passed to the `Log.{d,i,w,e}()`
methods, so implementations will need to manually append this
information if desired (possibly using
`Logger.appendThrowableString(String, Throwable)`).
* ExoPlayer: * ExoPlayer:
* Transformer: * Transformer:
* Parse EXIF rotation data for image inputs. * Parse EXIF rotation data for image inputs.

View File

@ -67,57 +67,61 @@ public final class Log {
Logger DEFAULT = Logger DEFAULT =
new Logger() { new Logger() {
@Override @Override
public void d(String tag, String message) { public void d(String tag, String message, @Nullable Throwable throwable) {
android.util.Log.d(tag, message); android.util.Log.d(tag, appendThrowableString(message, throwable));
} }
@Override @Override
public void i(String tag, String message) { public void i(String tag, String message, @Nullable Throwable throwable) {
android.util.Log.i(tag, message); android.util.Log.i(tag, appendThrowableString(message, throwable));
} }
@Override @Override
public void w(String tag, String message) { public void w(String tag, String message, @Nullable Throwable throwable) {
android.util.Log.w(tag, message); android.util.Log.w(tag, appendThrowableString(message, throwable));
} }
@Override @Override
public void e(String tag, String message) { public void e(String tag, String message, @Nullable Throwable throwable) {
android.util.Log.e(tag, message); android.util.Log.e(tag, appendThrowableString(message, throwable));
} }
}; };
/** /**
* Logs a debug-level message. * Logs a debug-level message with an optional associated {@link Throwable}.
* *
* @param tag The tag of the message. * @param tag The tag of the message.
* @param message The message. * @param message The message.
* @param throwable The {@link Throwable} associated with the message, or null if not specified.
*/ */
void d(String tag, String message); void d(String tag, String message, @Nullable Throwable throwable);
/** /**
* Logs an information-level message. * Logs an information-level message with an optional associated {@link Throwable}.
* *
* @param tag The tag of the message. * @param tag The tag of the message.
* @param message The message. * @param message The message.
* @param throwable The {@link Throwable} associated with the message, or null if not specified.
*/ */
void i(String tag, String message); void i(String tag, String message, @Nullable Throwable throwable);
/** /**
* Logs a warning-level message. * Logs a warning-level message with an optional associated {@link Throwable}.
* *
* @param tag The tag of the message. * @param tag The tag of the message.
* @param message The message. * @param message The message.
* @param throwable The {@link Throwable} associated with the message, or null if not specified.
*/ */
void w(String tag, String message); void w(String tag, String message, @Nullable Throwable throwable);
/** /**
* Logs an error-level message. * Logs an error-level message with an optional associated {@link Throwable}.
* *
* @param tag The tag of the message. * @param tag The tag of the message.
* @param message The message. * @param message The message.
* @param throwable The {@link Throwable} associated with the message, or null if not specified.
*/ */
void e(String tag, String message); void e(String tag, String message, @Nullable Throwable throwable);
} }
private static final Object lock = new Object(); private static final Object lock = new Object();
@ -176,83 +180,127 @@ public final class Log {
} }
/** /**
* @see android.util.Log#d(String, String) * Logs a debug-level message.
*
* @param tag The tag of the message.
* @param message The message.
*/ */
@Pure @Pure
public static void d(@Size(max = 23) String tag, String message) { public static void d(@Size(max = 23) String tag, String message) {
synchronized (lock) { synchronized (lock) {
if (logLevel == LOG_LEVEL_ALL) { if (logLevel == LOG_LEVEL_ALL) {
logger.d(tag, message); logger.d(tag, message, /* throwable= */ null);
} }
} }
} }
/** /**
* @see android.util.Log#d(String, String, Throwable) * Logs a debug-level message with an optional associated {@link Throwable}.
*
* @param tag The tag of the message.
* @param message The message.
* @param throwable The {@link Throwable} associated with the message, or null if not specified.
*/ */
@Pure @Pure
public static void d(@Size(max = 23) String tag, String message, @Nullable Throwable throwable) { public static void d(@Size(max = 23) String tag, String message, @Nullable Throwable throwable) {
d(tag, appendThrowableString(message, throwable)); synchronized (lock) {
if (logLevel == LOG_LEVEL_ALL) {
logger.d(tag, message, throwable);
}
}
} }
/** /**
* @see android.util.Log#i(String, String) * Logs an information-level message.
*
* @param tag The tag of the message.
* @param message The message.
*/ */
@Pure @Pure
public static void i(@Size(max = 23) String tag, String message) { public static void i(@Size(max = 23) String tag, String message) {
synchronized (lock) { synchronized (lock) {
if (logLevel <= LOG_LEVEL_INFO) { if (logLevel <= LOG_LEVEL_INFO) {
logger.i(tag, message); logger.i(tag, message, /* throwable= */ null);
} }
} }
} }
/** /**
* @see android.util.Log#i(String, String, Throwable) * Logs an information-level message with an optional associated {@link Throwable}.
*
* @param tag The tag of the message.
* @param message The message.
* @param throwable The {@link Throwable} associated with the message, or null if not specified.
*/ */
@Pure @Pure
public static void i(@Size(max = 23) String tag, String message, @Nullable Throwable throwable) { public static void i(@Size(max = 23) String tag, String message, @Nullable Throwable throwable) {
i(tag, appendThrowableString(message, throwable)); synchronized (lock) {
if (logLevel <= LOG_LEVEL_INFO) {
logger.i(tag, message, throwable);
}
}
} }
/** /**
* @see android.util.Log#w(String, String) * Logs a warning-level message.
*
* @param tag The tag of the message.
* @param message The message.
*/ */
@Pure @Pure
public static void w(@Size(max = 23) String tag, String message) { public static void w(@Size(max = 23) String tag, String message) {
synchronized (lock) { synchronized (lock) {
if (logLevel <= LOG_LEVEL_WARNING) { if (logLevel <= LOG_LEVEL_WARNING) {
logger.w(tag, message); logger.w(tag, message, /* throwable= */ null);
} }
} }
} }
/** /**
* @see android.util.Log#w(String, String, Throwable) * Logs a warning-level message with an optional associated {@link Throwable}..
*
* @param tag The tag of the message.
* @param message The message.
* @param throwable The {@link Throwable} associated with the message, or null if not specified.
*/ */
@Pure @Pure
public static void w(@Size(max = 23) String tag, String message, @Nullable Throwable throwable) { public static void w(@Size(max = 23) String tag, String message, @Nullable Throwable throwable) {
w(tag, appendThrowableString(message, throwable)); synchronized (lock) {
if (logLevel <= LOG_LEVEL_WARNING) {
logger.w(tag, message, throwable);
}
}
} }
/** /**
* @see android.util.Log#e(String, String) * Logs an error-level message.
*
* @param tag The tag of the message.
* @param message The message.
*/ */
@Pure @Pure
public static void e(@Size(max = 23) String tag, String message) { public static void e(@Size(max = 23) String tag, String message) {
synchronized (lock) { synchronized (lock) {
if (logLevel <= LOG_LEVEL_ERROR) { if (logLevel <= LOG_LEVEL_ERROR) {
logger.e(tag, message); logger.e(tag, message, /* throwable= */ null);
} }
} }
} }
/** /**
* @see android.util.Log#e(String, String, Throwable) * Logs an error-level message with an optional associated {@link Throwable}.
*
* @param tag The tag of the message.
* @param message The message.
* @param throwable The {@link Throwable} associated with the message, or null if not specified.
*/ */
@Pure @Pure
public static void e(@Size(max = 23) String tag, String message, @Nullable Throwable throwable) { public static void e(@Size(max = 23) String tag, String message, @Nullable Throwable throwable) {
e(tag, appendThrowableString(message, throwable)); synchronized (lock) {
if (logLevel <= LOG_LEVEL_ERROR) {
logger.e(tag, message, throwable);
}
}
} }
/** /**
@ -264,15 +312,17 @@ public final class Log {
* to avoid log spam. * to avoid log spam.
* *
* @param throwable The {@link Throwable}. * @param throwable The {@link Throwable}.
* @return The string representation of the {@link Throwable}. * @return The string representation of the {@link Throwable}, or null if {@code throwable} is
* null.
*/ */
@Nullable @Nullable
@Pure @Pure
public static String getThrowableString(@Nullable Throwable throwable) { public static String getThrowableString(@Nullable Throwable throwable) {
if (throwable == null) {
return null;
}
synchronized (lock) { synchronized (lock) {
if (throwable == null) { if (isCausedByUnknownHostException(throwable)) {
return null;
} else if (isCausedByUnknownHostException(throwable)) {
// UnknownHostException implies the device doesn't have network connectivity. // UnknownHostException implies the device doesn't have network connectivity.
// UnknownHostException.getMessage() may return a string that's more verbose than desired // UnknownHostException.getMessage() may return a string that's more verbose than desired
// for // for
@ -289,8 +339,11 @@ public final class Log {
} }
} }
/**
* Appends the result of {@link #getThrowableString(Throwable)} (if non-empty) to {@code message}.
*/
@Pure @Pure
private static String appendThrowableString(String message, @Nullable Throwable throwable) { public static String appendThrowableString(String message, @Nullable Throwable throwable) {
@Nullable String throwableString = getThrowableString(throwable); @Nullable String throwableString = getThrowableString(throwable);
if (!TextUtils.isEmpty(throwableString)) { if (!TextUtils.isEmpty(throwableString)) {
message += "\n " + throwableString.replace("\n", "\n ") + '\n'; message += "\n " + throwableString.replace("\n", "\n ") + '\n';