logcat에서 긴 메시지를 표시하는 방법


99

logcat에 긴 메시지를 표시하려고합니다. 메시지 길이가 1000 자 이상이면 깨집니다.

logcat에서 긴 메시지의 모든 문자를 표시하는 메커니즘은 무엇입니까?


6
서버에서 긴 문자열로 응답을 받고 있습니다.
Vasu 2011 년

1
그럼에도 불구하고 왜 전체 문자열을 인쇄하고 파일이나 데이터베이스에 쓰고 거기에서보기를 원
할까요?

logcat 문자열을 복사하고 notpad로 지나면 전체 1000 길이의 문자열을 볼 수 있습니다.
ilango j 2011 년

답변:


150

logcat이 길이를 1000으로 제한하면 String.subString ()으로 로깅하려는 문자열을 분할하고 조각으로 로깅 할 수 있습니다. 예를 들면 :

int maxLogSize = 1000;
for(int i = 0; i <= veryLongString.length() / maxLogSize; i++) {
    int start = i * maxLogSize;
    int end = (i+1) * maxLogSize;
    end = end > veryLongString.length() ? veryLongString.length() : end;
    Log.v(TAG, veryLongString.substring(start, end));
}

로그 고양이는 응답의 절반 만 인쇄합니다. 전체 응답의 길이를 어떻게 얻을 수 있습니까? 당신은 veryLongString.length ()라고 말했지만 여기서는 로그 고양이에 json 결과를 인쇄 할 때 응답의 절반 만 인쇄했습니다
Vasu

하지만 아이폰 콘솔에서 전체 응답 문자열을 받고 있습니다
Vasu

로그에 length ()를 작성하여 응답의 길이를 확인할 수 있습니다. 이 값이 예상 한 값이 아니면 로깅 문제가 아닐 수 있습니다.
spatulamania 2011 년

3
Android가 그렇게 어렵게 만든 다니 믿을 수 없습니다!
Alston 2015

1
나는 경우이 코드는, 마지막에 여분의 빈 로그 항목을 기록합니다 생각 veryLongString.length()의 배수입니다 maxLogSize. 아마 변경 <=<.
LarsH

29

spatulamania 답변에 대한 후속으로 나는 이것을 처리하는 래퍼 클래스를 작성했습니다. 가져 오기만 변경하면 모든 것이 기록됩니다.

public class Log {

    public static void d(String TAG, String message) {
        int maxLogSize = 2000;
        for(int i = 0; i <= message.length() / maxLogSize; i++) {
            int start = i * maxLogSize;
            int end = (i+1) * maxLogSize;
            end = end > message.length() ? message.length() : end;
            android.util.Log.d(TAG, message.substring(start, end));
        }
    }

}

24

이것은 spatulamania의 답변을 기반으로하며 좀 더 간결하며 끝에 빈 로그 메시지를 추가하지 않습니다.

final int chunkSize = 2048;
for (int i = 0; i < s.length(); i += chunkSize) {
    Log.d(TAG, s.substring(i, Math.min(s.length(), i + chunkSize)));
}

감사. 3000 개 이상의 기호는 권장되지 않으므로 사용합니다.
CoolMind

9

이것이 HttpLoggingInterceptor가있는 OkHttp가하는 방법입니다.

public void log(String message) {
  // Split by line, then ensure each line can fit into Log's maximum length.
  for (int i = 0, length = message.length(); i < length; i++) {
    int newline = message.indexOf('\n', i);
    newline = newline != -1 ? newline : length;
    do {
      int end = Math.min(newline, i + MAX_LOG_LENGTH);
      Log.d("OkHttp", message.substring(i, end));
      i = end;
    } while (i < newline);
  }
}

MAX_LOG_LENGTH 4000입니다.

여기서는 Log.d (디버그)와 하드 코딩 된 "OkHttp"태그를 사용합니다.

줄 바꿈 또는 최대 길이에 도달하면 로그를 분할합니다.

아래의이 클래스는 OkHttp가 모든 로그에서 수행하는 것과 동일한 작업을 수행하는 데 사용할 수있는 도우미 클래스입니다 (람다 지원이 Jack & Jill 또는 retrolambda를 지원하는 경우).

/**
 * Help printing logs splitting text on new line and creating multiple logs for too long texts
 */

public class LogHelper {

    private static final int MAX_LOG_LENGTH = 4000;

    public static void v(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.v(tag, line));
    }

    public static void d(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.d(tag, line));
    }

    public static void i(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.i(tag, line));
    }

    public static void w(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.w(tag, line));
    }

    public static void e(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.e(tag, line));
    }

    public static void v(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.v(tag, line));
    }

    public static void d(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.d(tag, line));
    }

    public static void i(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.i(tag, line));
    }

    public static void w(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.w(tag, line));
    }

    public static void e(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.e(tag, line));
    }

    private static void log(@Nullable String message, @NonNull LogCB callback) {
        if (message == null) {
            callback.log("null");
            return;
        }
        // Split by line, then ensure each line can fit into Log's maximum length.
        for (int i = 0, length = message.length(); i < length; i++) {
            int newline = message.indexOf('\n', i);
            newline = newline != -1 ? newline : length;
            do {
                int end = Math.min(newline, i + MAX_LOG_LENGTH);
                callback.log(message.substring(i, end));
                i = end;
            } while (i < newline);
        }
    }

    private static void log(@Nullable String message, @Nullable Throwable throwable, @NonNull LogCB callback) {
        if (throwable == null) {
            log(message, callback);
            return;
        }
        if (message != null) {
            log(message + "\n" + Log.getStackTraceString(throwable), callback);
        } else {
            log(Log.getStackTraceString(throwable), callback);
        }
    }

    private interface LogCB {
        void log(@NonNull String message);
    }
}

나는 그들의 코드에서 직접 찾고 있었지만 찾을 수 없었습니다. 감사합니다.
버그는

8

이 코드를 사용하여 logcat에 긴 메시지를 표시하십시오.

public void logLargeString(String str) {
    if(str.length() > 3000) {
        Log.i(TAG, str.substring(0, 3000));
        logLargeString(str.substring(3000));
    } else {
        Log.i(TAG, str); // continuation
    }
}

6
간단한 루프로 충분할 때 재귀를 사용하는 이유.
pellucide

3
나는 코드의 가독성과 재사용이 훌륭하다는 것을 알기 때문에 재귀의 팬입니다. 그러나이 꼬리 끝 재귀는 컴파일러가 최적화하지 않으면 스택 프레임을 빠르게 구축 할 수 있습니다 (Android 스튜디오에서는 그렇게 생각하지 않습니다). 즉, 다수의 재귀 호출을 유발하는 상당히 긴 메시지가있는 경우 StackOverflowError를 쉽게 만들 수 있습니다.
Luke

3

로그 메시지에서 줄 분할을 최소화하지 않기 위해 큰 문자열을 가져와 각 줄을 개별적으로 기록합니다.

void logMultilineString(String data) {
    for (String line : data.split("\n")) {
        logLargeString(line);
    }
}

void logLargeString(String data) {
    final int CHUNK_SIZE = 4076;  // Typical max logcat payload.
    int offset = 0;
    while (offset + CHUNK_SIZE <= data.length()) {
        Log.d(TAG, data.substring(offset, offset += CHUNK_SIZE));
    }
    if (offset < data.length()) {
        Log.d(TAG, data.substring(offset));
    }
}

1

다음은 @spatulamania 답변에 대한 Kotlin 버전입니다 (특히 게으른 / 똑똑한 사람들을위한) :

val maxLogSize = 1000
val stringLength = yourString.length
for (i in 0..stringLength / maxLogSize) {
    val start = i * maxLogSize
    var end = (i + 1) * maxLogSize
    end = if (end > yourString.length) yourString.length else end
    Log.v("YOURTAG", yourString.substring(start, end))
}

1

저는 Timber가이 문제에 대한 좋은 선택이라고 생각합니다. Timber는 logcat에서 메시지 청크를 자동으로 분할하고 인쇄합니다.

https://github.com/JakeWharton/timber

timber.log.Timber.DebugTree 정적 클래스에서 로그 메소드 구현을 볼 수 있습니다.


0

json 문자열을 인쇄하면 아래 코드를 사용할 수 있습니다.

    @JvmStatic
    fun j(level: Int, tag: String? = null, msg: String) {
        if (debug) {
            if (TextUtils.isEmpty(msg)) {
                p(level, tag, msg)
            } else {
                val message: String
                message = try {
                    when {
                        msg.startsWith("{") -> {
                            val jsonObject = JSONObject(msg)
                            jsonObject.toString(4)
                        }
                        msg.startsWith("[") -> {
                            val jsonArray = JSONArray(msg)
                            jsonArray.toString(4)
                        }
                        else -> msg
                    }
                } catch (e: JSONException) {
                    e.printStackTrace()
                    msg
                }
                p(level, tag, "╔═══════════════════════════════════════════════════════════════════════════════════════", false)
                val lines = message.split(LINE_SEPARATOR.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                for (line in lines) {
                    p(level, tag, "║ $line", false)
                }
                p(level, tag, "╚═══════════════════════════════════════════════════════════════════════════════════════", false)
            }
        }
    }

전체 코드

CXLogUtil.j ( "json-tag", "{}")

결과 미리보기


-3

쉬운 해결책을 위해 아래의 부착 지점 4 번 옵션에서 소프트 랩 사용 옵션을 사용 하면 도움이 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.