Improve logging
- Make sure logging of UnknownHostException indicates the failure reason - Indent stack traces inside event blocks in EventLogger - Don't log media URLs PiperOrigin-RevId: 302007601
This commit is contained in:
parent
c0d632936a
commit
429bdfb974
@ -223,7 +223,7 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
|
||||
responseByteStream = responseBody.byteStream();
|
||||
} catch (IOException e) {
|
||||
throw new HttpDataSourceException(
|
||||
"Unable to connect to " + dataSpec.uri, e, dataSpec, HttpDataSourceException.TYPE_OPEN);
|
||||
"Unable to connect", e, dataSpec, HttpDataSourceException.TYPE_OPEN);
|
||||
}
|
||||
|
||||
int responseCode = response.code();
|
||||
|
@ -21,6 +21,7 @@ import androidx.annotation.Nullable;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/** Wrapper around {@link android.util.Log} which allows to set the log level. */
|
||||
public final class Log {
|
||||
@ -69,7 +70,8 @@ public final class Log {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether stack traces of {@link Throwable}s will be logged to logcat.
|
||||
* Sets whether stack traces of {@link Throwable}s will be logged to logcat. Stack trace logging
|
||||
* is enabled by default.
|
||||
*
|
||||
* @param logStackTraces Whether stack traces will be logged.
|
||||
*/
|
||||
@ -86,11 +88,7 @@ public final class Log {
|
||||
|
||||
/** @see android.util.Log#d(String, String, Throwable) */
|
||||
public static void d(String tag, String message, @Nullable Throwable throwable) {
|
||||
if (!logStackTraces) {
|
||||
d(tag, appendThrowableMessage(message, throwable));
|
||||
} else if (logLevel == LOG_LEVEL_ALL) {
|
||||
android.util.Log.d(tag, message, throwable);
|
||||
}
|
||||
d(tag, appendThrowableString(message, throwable));
|
||||
}
|
||||
|
||||
/** @see android.util.Log#i(String, String) */
|
||||
@ -102,11 +100,7 @@ public final class Log {
|
||||
|
||||
/** @see android.util.Log#i(String, String, Throwable) */
|
||||
public static void i(String tag, String message, @Nullable Throwable throwable) {
|
||||
if (!logStackTraces) {
|
||||
i(tag, appendThrowableMessage(message, throwable));
|
||||
} else if (logLevel <= LOG_LEVEL_INFO) {
|
||||
android.util.Log.i(tag, message, throwable);
|
||||
}
|
||||
i(tag, appendThrowableString(message, throwable));
|
||||
}
|
||||
|
||||
/** @see android.util.Log#w(String, String) */
|
||||
@ -118,11 +112,7 @@ public final class Log {
|
||||
|
||||
/** @see android.util.Log#w(String, String, Throwable) */
|
||||
public static void w(String tag, String message, @Nullable Throwable throwable) {
|
||||
if (!logStackTraces) {
|
||||
w(tag, appendThrowableMessage(message, throwable));
|
||||
} else if (logLevel <= LOG_LEVEL_WARNING) {
|
||||
android.util.Log.w(tag, message, throwable);
|
||||
}
|
||||
w(tag, appendThrowableString(message, throwable));
|
||||
}
|
||||
|
||||
/** @see android.util.Log#e(String, String) */
|
||||
@ -134,18 +124,54 @@ public final class Log {
|
||||
|
||||
/** @see android.util.Log#e(String, String, Throwable) */
|
||||
public static void e(String tag, String message, @Nullable Throwable throwable) {
|
||||
if (!logStackTraces) {
|
||||
e(tag, appendThrowableMessage(message, throwable));
|
||||
} else if (logLevel <= LOG_LEVEL_ERROR) {
|
||||
android.util.Log.e(tag, message, throwable);
|
||||
e(tag, appendThrowableString(message, throwable));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of a {@link Throwable} suitable for logging, taking into
|
||||
* account whether {@link #setLogStackTraces(boolean)} stack trace logging} is enabled.
|
||||
*
|
||||
* <p>Stack trace logging may be unconditionally suppressed for some expected failure modes (e.g.,
|
||||
* {@link Throwable Throwables} that are expected if the device doesn't have network connectivity)
|
||||
* to avoid log spam.
|
||||
*
|
||||
* @param throwable The {@link Throwable}.
|
||||
* @return The string representation of the {@link Throwable}.
|
||||
*/
|
||||
@Nullable
|
||||
public static String getThrowableString(@Nullable Throwable throwable) {
|
||||
if (throwable == null) {
|
||||
return null;
|
||||
} else if (isCausedByUnknownHostException(throwable)) {
|
||||
// UnknownHostException implies the device doesn't have network connectivity.
|
||||
// UnknownHostException.getMessage() may return a string that's more verbose than desired for
|
||||
// logging an expected failure mode. Conversely, android.util.Log.getStackTraceString has
|
||||
// special handling to return the empty string, which can result in logging that doesn't
|
||||
// indicate the failure mode at all. Hence we special case this exception to always return a
|
||||
// concise but useful message.
|
||||
return "UnknownHostException (no network)";
|
||||
} else if (!logStackTraces) {
|
||||
return throwable.getMessage();
|
||||
} else {
|
||||
return android.util.Log.getStackTraceString(throwable).trim().replace("\t", " ");
|
||||
}
|
||||
}
|
||||
|
||||
private static String appendThrowableMessage(String message, @Nullable Throwable throwable) {
|
||||
if (throwable == null) {
|
||||
return message;
|
||||
private static String appendThrowableString(String message, @Nullable Throwable throwable) {
|
||||
@Nullable String throwableString = getThrowableString(throwable);
|
||||
if (!TextUtils.isEmpty(throwableString)) {
|
||||
message += "\n " + throwableString.replace("\n", "\n ") + '\n';
|
||||
}
|
||||
String throwableMessage = throwable.getMessage();
|
||||
return TextUtils.isEmpty(throwableMessage) ? message : message + " - " + throwableMessage;
|
||||
return message;
|
||||
}
|
||||
|
||||
private static boolean isCausedByUnknownHostException(@Nullable Throwable throwable) {
|
||||
while (throwable != null) {
|
||||
if (throwable instanceof UnknownHostException) {
|
||||
return true;
|
||||
}
|
||||
throwable = throwable.getCause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +477,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
playbackInfo = playbackInfo.copyWithPlaybackError(e);
|
||||
maybeNotifyPlaybackInfoChanged();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Source error.", e);
|
||||
Log.e(TAG, "Source error", e);
|
||||
stopInternal(
|
||||
/* forceResetRenderers= */ false,
|
||||
/* resetPositionAndState= */ false,
|
||||
@ -485,7 +485,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
playbackInfo = playbackInfo.copyWithPlaybackError(ExoPlaybackException.createForSource(e));
|
||||
maybeNotifyPlaybackInfoChanged();
|
||||
} catch (RuntimeException | OutOfMemoryError e) {
|
||||
Log.e(TAG, "Internal runtime error.", e);
|
||||
Log.e(TAG, "Internal runtime error", e);
|
||||
ExoPlaybackException error =
|
||||
e instanceof OutOfMemoryError
|
||||
? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e)
|
||||
|
@ -279,8 +279,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
||||
try {
|
||||
connection = makeConnection(dataSpec);
|
||||
} catch (IOException e) {
|
||||
throw new HttpDataSourceException("Unable to connect to " + dataSpec.uri.toString(), e,
|
||||
dataSpec, HttpDataSourceException.TYPE_OPEN);
|
||||
throw new HttpDataSourceException(
|
||||
"Unable to connect", e, dataSpec, HttpDataSourceException.TYPE_OPEN);
|
||||
}
|
||||
|
||||
String responseMessage;
|
||||
@ -289,8 +289,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
||||
responseMessage = connection.getResponseMessage();
|
||||
} catch (IOException e) {
|
||||
closeConnectionQuietly();
|
||||
throw new HttpDataSourceException("Unable to connect to " + dataSpec.uri.toString(), e,
|
||||
dataSpec, HttpDataSourceException.TYPE_OPEN);
|
||||
throw new HttpDataSourceException(
|
||||
"Unable to connect", e, dataSpec, HttpDataSourceException.TYPE_OPEN);
|
||||
}
|
||||
|
||||
// Check for a valid response code.
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.util;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
@ -209,7 +210,7 @@ public class EventLogger implements AnalyticsListener {
|
||||
logd(eventTime, "tracks", "[]");
|
||||
return;
|
||||
}
|
||||
logd("tracks [" + getEventTimeString(eventTime) + ", ");
|
||||
logd("tracks [" + getEventTimeString(eventTime));
|
||||
// Log tracks associated to renderers.
|
||||
int rendererCount = mappedTrackInfo.getRendererCount();
|
||||
for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) {
|
||||
@ -293,7 +294,7 @@ public class EventLogger implements AnalyticsListener {
|
||||
|
||||
@Override
|
||||
public void onMetadata(EventTime eventTime, Metadata metadata) {
|
||||
logd("metadata [" + getEventTimeString(eventTime) + ", ");
|
||||
logd("metadata [" + getEventTimeString(eventTime));
|
||||
printMetadata(metadata, " ");
|
||||
logd("]");
|
||||
}
|
||||
@ -485,27 +486,26 @@ public class EventLogger implements AnalyticsListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an error message and exception.
|
||||
* Logs an error message.
|
||||
*
|
||||
* @param msg The message to log.
|
||||
* @param tr The exception to log.
|
||||
*/
|
||||
protected void loge(String msg, @Nullable Throwable tr) {
|
||||
Log.e(tag, msg, tr);
|
||||
protected void loge(String msg) {
|
||||
Log.e(tag, msg);
|
||||
}
|
||||
|
||||
// Internal methods
|
||||
|
||||
private void logd(EventTime eventTime, String eventName) {
|
||||
logd(getEventString(eventTime, eventName));
|
||||
logd(getEventString(eventTime, eventName, /* eventDescription= */ null, /* throwable= */ null));
|
||||
}
|
||||
|
||||
private void logd(EventTime eventTime, String eventName, String eventDescription) {
|
||||
logd(getEventString(eventTime, eventName, eventDescription));
|
||||
logd(getEventString(eventTime, eventName, eventDescription, /* throwable= */ null));
|
||||
}
|
||||
|
||||
private void loge(EventTime eventTime, String eventName, @Nullable Throwable throwable) {
|
||||
loge(getEventString(eventTime, eventName), throwable);
|
||||
loge(getEventString(eventTime, eventName, /* eventDescription= */ null, throwable));
|
||||
}
|
||||
|
||||
private void loge(
|
||||
@ -513,7 +513,7 @@ public class EventLogger implements AnalyticsListener {
|
||||
String eventName,
|
||||
String eventDescription,
|
||||
@Nullable Throwable throwable) {
|
||||
loge(getEventString(eventTime, eventName, eventDescription), throwable);
|
||||
loge(getEventString(eventTime, eventName, eventDescription, throwable));
|
||||
}
|
||||
|
||||
private void printInternalError(EventTime eventTime, String type, Exception e) {
|
||||
@ -526,12 +526,21 @@ public class EventLogger implements AnalyticsListener {
|
||||
}
|
||||
}
|
||||
|
||||
private String getEventString(EventTime eventTime, String eventName) {
|
||||
return eventName + " [" + getEventTimeString(eventTime) + "]";
|
||||
}
|
||||
|
||||
private String getEventString(EventTime eventTime, String eventName, String eventDescription) {
|
||||
return eventName + " [" + getEventTimeString(eventTime) + ", " + eventDescription + "]";
|
||||
private String getEventString(
|
||||
EventTime eventTime,
|
||||
String eventName,
|
||||
@Nullable String eventDescription,
|
||||
@Nullable Throwable throwable) {
|
||||
String eventString = eventName + " [" + getEventTimeString(eventTime);
|
||||
if (eventDescription != null) {
|
||||
eventString += ", " + eventDescription;
|
||||
}
|
||||
@Nullable String throwableString = Log.getThrowableString(throwable);
|
||||
if (!TextUtils.isEmpty(throwableString)) {
|
||||
eventString += "\n " + throwableString.replace("\n", "\n ") + '\n';
|
||||
}
|
||||
eventString += "]";
|
||||
return eventString;
|
||||
}
|
||||
|
||||
private String getEventTimeString(EventTime eventTime) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user