Android - Set max length of logcat messages

2019-01-01 15:45发布

By default, it seems that logcat will truncate any log message that it considers to be "too long". This happens both inside of Eclipse and when running logcat on the command line using adb -d logcat, and is truncating some important debugging messages.

Is there any way to increase the maximum string length supported by logcat to get it to stop truncating the debug information? The official documentation implies that there may not be, but maybe logcat supports some additional options not mentioned there?

10条回答
初与友歌
2楼-- · 2019-01-01 15:59

providing my own take on Travis's solution,

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

take advantage of the fact that Log.println() returns the number of bytes written to avoid hardcoding "4000". then, recursively call yourself on the part of the message that couldn't be logged until there's nothing left.

查看更多
浅入江南
3楼-- · 2019-01-01 16:00

Ok, interesting. I was disappointed to see that the answer was "you can't really expand it". My initial thought was to break it up so I could view the whole thing, so here I share with you how I do just that (not that it's anything fancy nor is it near efficient, but it gets the job done in a pinch):

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

Edited to show the last string!

查看更多
一个人的天荒地老
4楼-- · 2019-01-01 16:01

The code below is a refinement of what was posted by Mark Buikema. It breaks the string at new lines. Useful for logging long JSON strings.

  public static void dLong(String theMsg)
  {
    final int MAX_INDEX = 4000;
    final int MIN_INDEX = 3000;

    // String to be logged is longer than the max...
    if (theMsg.length() > MAX_INDEX)
    {
      String theSubstring = theMsg.substring(0, MAX_INDEX);
      int    theIndex = MAX_INDEX;

      // Try to find a substring break at a line end.
      theIndex = theSubstring.lastIndexOf('\n');
      if (theIndex >= MIN_INDEX)
      {
        theSubstring = theSubstring.substring(0, theIndex);
      }
      else
      {
        theIndex = MAX_INDEX;
      }

      // Log the substring.
      Log.d(APP_LOG_TAG, theSubstring);

      // Recursively log the remainder.
      dLong(theMsg.substring(theIndex));
    }

    // String to be logged is shorter than the max...
    else
    {
      Log.d(APP_LOG_TAG, theMsg);
    }
  }
查看更多
笑指拈花
5楼-- · 2019-01-01 16:02

Here is the code I use--it truncates the lines at the 4000 limit while also breaking the line at new lines rather than in the middles of the line. Makes for an easier to read log file.

Usage:

Logger.debugEntire("....");

Implementation:

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;
    }
}
查看更多
低头抚发
6楼-- · 2019-01-01 16:04
for( String line : logMesg.split("\n") ) {
    Log.d( TAG, line );
}
查看更多
闭嘴吧你
7楼-- · 2019-01-01 16:11

I dont know any option to increase the length of logcat , but we can find the different logs like main log , event log etc..The main log usually contains everything its length goes upto 4Mb.. So you may able to get what you lost in log terminal. Path is: \data\logger.

查看更多
登录 后发表回答