Cara menampilkan pesan panjang di logcat

99

Saya mencoba menampilkan pesan panjang di logcat. Jika panjang pesan lebih dari 1000 karakter, itu akan rusak.

Bagaimana mekanisme untuk menampilkan semua karakter pesan panjang di logcat?

Vasu
sumber
6
Saya mendapatkan respon dari server sebagai string panjang.
Vasu
1
Bahkan mengapa Anda ingin mencetak seluruh string, menuliskannya ke file atau database dan melihatnya di sana - jika untuk debugging
Rahul Choudhary
salin string logcat Anda dan lewati ke notpad, Anda dapat melihat 1000 panjang string penuh.
ilango j
stackoverflow.com/questions/8888654/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

150

Jika logcat membatasi panjangnya pada 1000 maka Anda dapat membagi string yang ingin Anda catat dengan String.subString () dan memasukkannya dalam beberapa bagian. Sebagai contoh:

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));
}
spatulamania
sumber
Pencetakan log cat hanya setengah dari respon .. bagaimana saya bisa mendapatkan panjang dari keseluruhan respon. Anda mengatakan bahwa veryLongString.length () tetapi di sini dicetak hanya setengah dari respons ketika saya mencetak hasil json di log cat
Vasu
Tetapi di konsol iphone saya mendapatkan seluruh rangkaian respons
Vasu
Anda bisa memeriksa panjang respon dengan menulis length () ke log. Jika nilai ini tidak seperti yang Anda harapkan, masalahnya mungkin bukan pada logging.
spatulamania
3
Tidak percaya Android membuatnya begitu sulit!
Alston
1
Saya pikir kode ini akan mencatat entri log tambahan yang kosong di bagian akhir, jika veryLongString.length()merupakan kelipatan maxLogSize. Mungkin ubah <=menjadi <.
LarsH
29

Sebagai tindak lanjut dari jawaban spatulamania saya menulis kelas pembungkus yang menangani ini untuk Anda. Anda hanya perlu mengubah impor dan itu akan mencatat semuanya

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

}
jiduvah
sumber
24

Ini dibangun berdasarkan jawaban spatulamania, sedikit lebih ringkas, dan tidak akan menambahkan pesan log kosong di akhir:

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)));
}
LarsH
sumber
Terima kasih. Lebih dari 3000 simbol tidak disarankan, saya menggunakannya.
CoolMind
9

Beginilah cara OkHttp dengan HttpLoggingInterceptor melakukannya:

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 adalah 4000.

Di sini ia menggunakan Log.d (debug) dan tag "OkHttp" yang di-hardcode.

Ini membagi log di baris baru atau saat mencapai panjang maksimal.

Kelas di bawah ini adalah kelas pembantu yang dapat Anda gunakan (jika Anda memiliki dukungan lambda, lemparkan Jack & Jill atau retrolambda) untuk melakukan hal yang sama yang dilakukan OkHttp pada log mana pun:

/**
 * 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);
    }
}
Daniele Segato
sumber
Saya mencarinya sendiri di kode mereka tetapi tidak dapat menemukannya. Terima kasih.
Bug Terjadi
8

Coba bagian kode ini untuk menampilkan pesan panjang di 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
    }
}
mani
sumber
6
ketika loop sederhana sudah cukup, mengapa menggunakan rekursi.
pellucide
3
Saya penggemar rekursi karena menurut saya kesiapan dan penggunaan kembali kode itu bagus. Namun rekursi ujung ekor ini dapat membangun tumpukan frame dengan cepat jika kompiler Anda tidak mengoptimalkannya (yang saya tidak percaya studio Android melakukannya). Ini berarti bahwa jika Anda memiliki pesan yang sangat panjang yang menyebabkan banyaknya panggilan rekursif, Anda dapat dengan mudah membuat StackOverflowError.
Lukas
3

Agar tidak meminimalkan garis pemisahan di seluruh pesan log, saya mengambil string besar dan mencatat setiap baris secara terpisah.

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));
    }
}
vonWippersnap
sumber
1

Berikut adalah versi Kotlin untuk jawaban @spatulamania (terutama untuk orang yang malas / pintar):

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))
}
Filipe Brito
sumber
1

Saya menganggap Kayu sebagai pilihan yang baik untuk masalah ini. Timber secara otomatis membagi dan mencetak potongan pesan di logcat.

https://github.com/JakeWharton/timber

Anda dapat melihat implementasi metode log di kelas statis timber.log.Timber.DebugTree.

Jaelson Wagner
sumber
0

Jika print json string, bisa menggunakan kode di bawah ini

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

kode lengkap

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

hasil pratinjau

Michael Mao
sumber
-3

Untuk solusi yang mudah, gunakan opsi Gunakan bungkus lembut di bawah lampirkan poin no 4 opsi mungkin membantu Anda.

Mohit Suthar
sumber