developer tip

Android-logcat 메시지의 최대 길이 설정

optionbox 2020. 9. 5. 09:44
반응형

Android-logcat 메시지의 최대 길이 설정


기본적으로 logcat은 "너무 긴"것으로 간주되는 모든 로그 메시지를 자릅니다. 이것은 Eclipse 내부에서와를 사용하여 명령 줄에서 logcat을 실행할 때 발생하며 adb -d logcat중요한 디버깅 메시지가 잘립니다.

디버그 정보 자르기를 중지하도록 logcat에서 지원하는 최대 문자열 길이를 늘리는 방법이 있습니까? 공식 문서가 존재하지 않을 수 있음을 의미한다,하지만 어쩌면 지원 로그 캣 몇 가지 추가 옵션이 언급되지?


바이너리 로그 ( /dev/log/events)에 대한 logcat에는 고정 크기 버퍼가 있으며이 제한은 1024 바이트입니다. 바이너리가 아닌 로그의 경우에도 제한이 있습니다.

#define LOGGER_ENTRY_MAX_LEN        (4*1024)
#define LOGGER_ENTRY_MAX_PAYLOAD (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))

따라서 바이너리 및 비 바이너리 로그의 실제 메시지 크기는 ~ 4076 바이트입니다. 커널 로거 인터페이스는이 LOGGER_ENTRY_MAX_PAYLOAD제한을 부과합니다 .

liblog 소스 (logcat에서 사용)는 다음과 같이 말합니다.

  • 커널 로그 드라이버에 의해 메시지가 잘 렸을 수 있습니다.

logcat 바이너리를 사용하지 않는 nxlog 도구를 권장 하지만 커널의 제한으로 인해 문제가 해결 될 것 같지 않습니다. 그럼에도 불구하고 시도해 볼 가치가 있습니다. (면책 조항 : 저자입니다.)


좋아요, 흥미 롭군요 대답이 "정말로 확장 할 수 없다"는 것을보고 실망했습니다. 나의 초기 생각은 모든 것을 볼 수 있도록 그것을 깨뜨리는 것이 었습니다. 그래서 여기에서 제가하는 방법을 여러분과 공유합니다. (멋지거나 거의 효율적이지는 않지만, 작업을 한꺼번에 완료합니다) :

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

마지막 문자열을 표시하도록 편집되었습니다!


반복적으로 여러 조각으로 나눕니다.

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

내가 사용하는 코드는 다음과 같습니다. 4000 제한에서 줄을 자르고 줄 중간이 아닌 새 줄에서 줄을 끊습니다. 로그 파일을 더 쉽게 읽을 수 있습니다.

용법:

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

이행:

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

아래 코드는 Mark Buikema가 게시 한 내용을 수정 한 것입니다. 새 줄에서 문자열을 끊습니다. 긴 JSON 문자열을 로깅하는 데 유용합니다.

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

이 페이징 로직

    /*
     * 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));
            }
        }
    }

}

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

Log.println()"4000"하드 코딩을 피하기 위해 쓰여진 바이트 수 반환 한다는 사실을 이용하십시오 . 그런 다음 아무것도 남지 않을 때까지 기록 할 수없는 메시지 부분에서 자신을 재귀 적으로 호출합니다.


If your log is very long (eg. logging entire dump of your database for debugging reasons etc.) it may happen that logcat prevents excessive logging. To work around this you can add a timeout evry x milliseconds.

/**
 * 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);
}

Beware, only use this for debugging purpose as it may halts blocks main thread.


int i = 3000;
while (sb.length() > i) {
    Log.e(TAG, "Substring: "+ sb.substring(0, i));
    sb = sb.substring(i);
}
Log.e(TAG, "Substring: "+ sb);

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.

참고URL : https://stackoverflow.com/questions/8888654/android-set-max-length-of-logcat-messages

반응형