Android: establece la longitud máxima de los mensajes de logcat
De forma predeterminada, parece que logcat truncará cualquier mensaje de registro que considere "demasiado largo". Esto ocurre tanto dentro de Eclipse como al ejecutar logcat en la línea de comandos usando adb -d logcat
y está truncando algunos mensajes importantes de depuración.
¿Hay alguna forma de aumentar la longitud de cadena máxima admitida por logcat para que deje de truncar la información de depuración? La documentación oficial implica que no puede haber, pero tal vez Logcat apoya algunas opciones adicionales que no se menciona allí?
- Registrar el dispositivo en el archivo
- Android: establece el nivel de registro predeterminado en DEBUG
- Niveles de registro de Android
- No Commons Iniciar sesión en Android?
- Cómo agregar nombres de clase y función automáticamente a mi registro
- Niveles de registro de Android
- Android.util.Config.DEBUG siempre es falso incluso cuando se desarrollan y depuran en eclipse. ¿Por qué?
- Aplicación para Android que usa android.permission.READ_LOGS - ¿es eso descortés?
- Android Production Logging Best Practice
- E / Surface: getSlotFromBufferLocked: buffer desconocido: 0xab7519c0
- ¿Cómo registrar un int en Android?
- Mostrar mensajes de registro en la pantalla para la aplicación de Android
- ¿Cómo suprimir el registro con Google Analytics 7.3?
Hay un búfer de tamaño fijo en logcat para registros binarios ( /dev/log/events
) y este límite es 1024 bytes. Para los registros no binarios también hay un límite:
#define LOGGER_ENTRY_MAX_LEN (4*1024) #define LOGGER_ENTRY_MAX_PAYLOAD (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
Por lo tanto, el tamaño de mensaje real para los registros binarios y no binarios es ~ 4076 bytes. La interfaz del registrador de kernel impone este límite LOGGER_ENTRY_MAX_PAYLOAD
.
Las fuentes de liblog (utilizadas por logcat) también dicen:
- El mensaje puede haber sido truncado por el controlador de registro del kernel.
Te recomiendo la herramienta nxlog que no usa el binario logcat, pero debido a las limitaciones en el kernel dudo que solucione tu problema. Sin embargo, podría valer la pena intentarlo. (Descargo de responsabilidad: soy el autor.)
Ok, interesante. Me decepcionó ver que la respuesta era "realmente no se puede ampliar". Mi idea inicial fue romperlo para que pudiera verlo todo, así que aquí comparto con ustedes cómo lo hago (no es que sea nada extravagante, tampoco está cerca de eficiente, pero consigue que el trabajo se realice en un pellizco):
if (sb.length() > 4000) { Log.v(TAG, "sb.length = " + sb.length()); int chunkCount = sb.length() / 4000; // integer division for (int i = 0; i <= chunkCount; i++) { int max = 4000 * (i + 1); if (max >= sb.length()) { Log.v(TAG, "chunk " + i + " of " + chunkCount + ":" + sb.substring(4000 * i)); } else { Log.v(TAG, "chunk " + i + " of " + chunkCount + ":" + sb.substring(4000 * i, max)); } } } else { Log.v(TAG, sb.toString()); }
¡Editado para mostrar la última cuerda!
Romperlo en varias piezas recursivamente.
public static void largeLog(String tag, String content) { if (content.length() > 4000) { Log.d(tag, content.substring(0, 4000)); largeLog(tag, content.substring(4000)); } else { Log.d(tag, content); } }
for( String line : logMesg.split("\n") ) { Log.d( TAG, line ); }
Aquí está el código que utilizo – trunca las líneas en el límite 4000 mientras que también rompe la línea en las nuevas líneas más bien que en los medios de la línea. Hace un archivo de registro más fácil de leer.
Uso:
Logger.debugEntire("....");
Implementación:
package ...; import android.util.Log; import java.util.Arrays; public class Logger { private static final String LOG_TAG = "MyRockingApp"; /** @see <a href="http://stackoverflow.com/a/8899735" /> */ private static final int ENTRY_MAX_LEN = 4000; /** * @param args If the last argument is an exception than it prints out the stack trace, and there should be no {} * or %s placeholder for it. */ public static void d(String message, Object... args) { log(Log.DEBUG, false, message, args); } /** * Display the entire message, showing multiple lines if there are over 4000 characters rather than truncating it. */ public static void debugEntire(String message, Object... args) { log(Log.DEBUG, true, message, args); } public static void i(String message, Object... args) { log(Log.INFO, false, message, args); } public static void w(String message, Object... args) { log(Log.WARN, false, message, args); } public static void e(String message, Object... args) { log(Log.ERROR, false, message, args); } private static void log(int priority, boolean ignoreLimit, String message, Object... args) { String print; if (args != null && args.length > 0 && args[args.length-1] instanceof Throwable) { Object[] truncated = Arrays.copyOf(args, args.length -1); Throwable ex = (Throwable) args[args.length-1]; print = formatMessage(message, truncated) + '\n' + android.util.Log.getStackTraceString(ex); } else { print = formatMessage(message, args); } if (ignoreLimit) { while (!print.isEmpty()) { int lastNewLine = print.lastIndexOf('\n', ENTRY_MAX_LEN); int nextEnd = lastNewLine != -1 ? lastNewLine : Math.min(ENTRY_MAX_LEN, print.length()); String next = print.substring(0, nextEnd /*exclusive*/); android.util.Log.println(priority, LOG_TAG, next); if (lastNewLine != -1) { // Don't print out the \n twice. print = print.substring(nextEnd+1); } else { print = print.substring(nextEnd); } } } else { android.util.Log.println(priority, LOG_TAG, print); } } private static String formatMessage(String message, Object... args) { String formatted; try { /* * {} is used by SLF4J so keep it compatible with that as it's easy to forget to use %s when you are * switching back and forth between server and client code. */ formatted = String.format(message.replaceAll("\\{\\}", "%s"), args); } catch (Exception ex) { formatted = message + Arrays.toString(args); } return formatted; } }
Esta lógica de paginación
/* * StringBuffer sb - long text which want to show in multiple lines * int lenth - lenth of line need */ public static void showInPage(StringBuffer sb, int lenth) { System.out.println("sb.length = " + sb.length()); if (sb.length() > lenth) { int chunkCount = sb.length() / lenth; // integer division if ((chunkCount % lenth) > 1) chunkCount++; for (int i = 0; i < chunkCount; i++) { int max = lenth * (i + 1); if (max >= sb.length()) { System.out.println(""); System.out.println("chunk " + i + " of " + chunkCount + ":" + sb.substring(lenth * i)); } else { System.out.println(""); System.out.println("chunk " + i + " of " + chunkCount + ":" + sb.substring(lenth * i, max)); } } } }
Proporcionando mi propia toma en la solución de Travis,
void d(String msg) { println(Log.DEBUG, msg); } private void println(int priority, String msg) { int l = msg.length(); int c = Log.println(priority, TAG, msg); if (c < l) { return c + println(priority, TAG, msg.substring(c+1)); } else { return c; } }
Aproveche el hecho de que Log.println()
devuelve el número de bytes escritos para evitar la codificación "4000". Entonces, recursivamente se llama por la parte del mensaje que no pudo ser registrado hasta que no queda nada.
Si su registro es muy largo (por ejemplo, registrar todo el volcado de su base de datos por motivos de depuración, etc.) puede ocurrir que logcat evite el registro excesivo. Para evitar esto, puede agregar un tiempo de espera evry x milisegundos.
/** * Used for very long messages, splits it into equal chunks and logs each individual to * work around the logcat max message length. Will log with {@link Log#d(String, String)}. * * @param tag used in for logcat * @param message long message to log */ public static void longLogDebug(final String tag, @NonNull String message) { int i = 0; final int maxLogLength = 1000; while (message.length() > maxLogLength) { Log.d(tag, message.substring(0, maxLogLength)); message = message.substring(maxLogLength); i++; if (i % 100 == 0) { StrictMode.noteSlowCall("wait to flush logcat"); SystemClock.sleep(32); } } Log.d(tag, message); }
Tenga cuidado, sólo utilice esto para fines de depuración, ya que puede detener bloques de hilo principal.
No sé ninguna opción para aumentar la longitud del logcat, pero podemos encontrar los diversos registros como registro principal, registro de acontecimiento etc. El registro principal contiene generalmente todo su longitud va upto 4Mb. Así que usted puede poder conseguir lo que usted perdió En terminal de registro. La ruta es: \ data \ logger.
- Android RecyclerView: notifyDataSetChanged () IllegalStateException
- Media Player llamado en estado 0, error (-38,0)