From 9c24a2c03daca5964de1546c09c84efe617657b7 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 8 Sep 2022 03:26:38 +0000 Subject: [PATCH] Overloads Slogf d, v, and i, methods to take an exception Also fixed some negative tests that were calling the wrong methods. Test: atest FrameworksMockingServicesTests:SlogfTest Fixes: 245335748 Change-Id: I6c44b2e3d3a55d3def6a91c81563a7a4520e8b8f --- .../java/com/android/server/utils/Slogf.java | 46 +++++++++++++++ .../com/android/server/utils/SlogfTest.java | 58 ++++++++++++++++++- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/utils/Slogf.java b/services/core/java/com/android/server/utils/Slogf.java index bbc541438c828..e88ac63615ca2 100644 --- a/services/core/java/com/android/server/utils/Slogf.java +++ b/services/core/java/com/android/server/utils/Slogf.java @@ -161,6 +161,21 @@ public final class Slogf { v(tag, getMessage(format, args)); } + /** + * Logs a {@link Log.VEBOSE} message with an exception + * + *

Note: the message will only be formatted if {@link Log#VERBOSE} logging + * is enabled for the given {@code tag}, but the compiler will still create an intermediate + * array of the objects for the {@code vargars}, which could affect garbage collection. So, if + * you're calling this method in a critical path, make sure to explicitly do the check before + * calling it. + */ + public static void v(String tag, Exception exception, String format, @Nullable Object... args) { + if (!isLoggable(tag, Log.VERBOSE)) return; + + v(tag, getMessage(format, args), exception); + } + /** * Logs a {@link Log.DEBUG} message. * @@ -176,6 +191,21 @@ public final class Slogf { d(tag, getMessage(format, args)); } + /** + * Logs a {@link Log.DEBUG} message with an exception + * + *

Note: the message will only be formatted if {@link Log#DEBUG} logging + * is enabled for the given {@code tag}, but the compiler will still create an intermediate + * array of the objects for the {@code vargars}, which could affect garbage collection. So, if + * you're calling this method in a critical path, make sure to explicitly do the check before + * calling it. + */ + public static void d(String tag, Exception exception, String format, @Nullable Object... args) { + if (!isLoggable(tag, Log.DEBUG)) return; + + d(tag, getMessage(format, args), exception); + } + /** * Logs a {@link Log.INFO} message. * @@ -191,6 +221,21 @@ public final class Slogf { i(tag, getMessage(format, args)); } + /** + * Logs a {@link Log.INFO} message with an exception + * + *

Note: the message will only be formatted if {@link Log#INFO} logging + * is enabled for the given {@code tag}, but the compiler will still create an intermediate + * array of the objects for the {@code vargars}, which could affect garbage collection. So, if + * you're calling this method in a critical path, make sure to explicitly do the check before + * calling it. + */ + public static void i(String tag, Exception exception, String format, @Nullable Object... args) { + if (!isLoggable(tag, Log.INFO)) return; + + i(tag, getMessage(format, args), exception); + } + /** * Logs a {@link Log.WARN} message. * @@ -220,6 +265,7 @@ public final class Slogf { w(tag, getMessage(format, args), exception); } + /** * Logs a {@link Log.ERROR} message. * diff --git a/services/tests/mockingservicestests/src/com/android/server/utils/SlogfTest.java b/services/tests/mockingservicestests/src/com/android/server/utils/SlogfTest.java index 3e8cef9afc152..ae25c1bb3db8b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/utils/SlogfTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/utils/SlogfTest.java @@ -102,6 +102,24 @@ public final class SlogfTest { verify(()-> Slog.v(eq(TAG), any()), never()); } + @Test + public void testV_msgFormattedWithException_enabled() { + enableLogging(Log.VERBOSE); + + Slogf.v(TAG, mException, "msg in a %s", "bottle"); + + verify(()-> Slog.v(TAG, "msg in a bottle", mException)); + } + + @Test + public void testV_msgFormattedWithException_disabled() { + disableLogging(Log.VERBOSE); + + Slogf.v(TAG, "msg in a %s", "bottle"); + + verify(()-> Slog.v(eq(TAG), any(String.class), any(Throwable.class)), never()); + } + @Test public void testD_msg() { Slogf.d(TAG, "msg"); @@ -134,6 +152,24 @@ public final class SlogfTest { verify(()-> Slog.d(eq(TAG), any()), never()); } + @Test + public void testD_msgFormattedWithException_enabled() { + enableLogging(Log.DEBUG); + + Slogf.d(TAG, mException, "msg in a %s", "bottle"); + + verify(()-> Slog.d(TAG, "msg in a bottle", mException)); + } + + @Test + public void testD_msgFormattedWithException_disabled() { + disableLogging(Log.DEBUG); + + Slogf.d(TAG, mException, "msg in a %s", "bottle"); + + verify(()-> Slog.d(eq(TAG), any(String.class), any(Throwable.class)), never()); + } + @Test public void testI_msg() { Slogf.i(TAG, "msg"); @@ -166,6 +202,24 @@ public final class SlogfTest { verify(()-> Slog.i(eq(TAG), any()), never()); } + @Test + public void testI_msgFormattedWithException_enabled() { + enableLogging(Log.INFO); + + Slogf.i(TAG, mException, "msg in a %s", "bottle"); + + verify(()-> Slog.i(TAG, "msg in a bottle", mException)); + } + + @Test + public void testI_msgFormattedWithException_disabled() { + disableLogging(Log.INFO); + + Slogf.i(TAG, mException, "msg in a %s", "bottle"); + + verify(()-> Slog.i(eq(TAG), any(String.class), any(Throwable.class)), never()); + } + @Test public void testW_msg() { Slogf.w(TAG, "msg"); @@ -218,7 +272,7 @@ public final class SlogfTest { public void testW_msgFormattedWithException_disabled() { disableLogging(Log.WARN); - Slogf.w(TAG, "msg in a %s", "bottle"); + Slogf.w(TAG, mException, "msg in a %s", "bottle"); verify(()-> Slog.w(eq(TAG), any(String.class), any(Throwable.class)), never()); } @@ -268,7 +322,7 @@ public final class SlogfTest { public void testE_msgFormattedWithException_disabled() { disableLogging(Log.ERROR); - Slogf.e(TAG, "msg in a %s", "bottle"); + Slogf.e(TAG, mException, "msg in a %s", "bottle"); verify(()-> Slog.e(eq(TAG), any(String.class), any(Throwable.class)), never()); }