অ্যান্ড্রয়েড - লগক্যাট বার্তাগুলির সর্বাধিক দৈর্ঘ্য সেট করুন


101

ডিফল্টরূপে, দেখে মনে হয় যে লগক্যাট কোনও লগ বার্তা কে একে "খুব দীর্ঘ" বলে মনে করে কাটাবে। এটি Eclipse এর অভ্যন্তরে এবং কমান্ড লাইনে লগক্যাটটি ব্যবহার করার সময় উভয় ক্ষেত্রেই ঘটে এবং adb -d logcatকিছু গুরুত্বপূর্ণ ডিবাগিং বার্তাগুলি ছাঁটাচ্ছে ।

ডিবাগের তথ্য কাটা থামানোর জন্য লগক্যাট দ্বারা সমর্থিত সর্বোচ্চ স্ট্রিং দৈর্ঘ্য বাড়ানোর কোনও উপায় আছে কি? সরকারী ডকুমেন্টেশন যে বোঝা নেই হতে পারে, কিন্তু হয়তো সমর্থন Logcat কিছু অতিরিক্ত অপশন সেখানে উল্লেখ না?





4
@ জোশকোরিয়া আমি মোটামুটি বাফার আকারকে বোঝায় যে এটি একটি ভাল সদৃশ বলে মনে হয় না, এবং এটি প্রতি লগ বার্তা।
রায়ান এম

4
@ রেয়ানাম আহ আমার খারাপ, আমি অন্য প্রশ্নটি ভুল বুঝেছি। ধন্যবাদ, ডুপ হিসাবে চিহ্ন অপসারণ।
জোশ Correia

উত্তর:


46

বাইনারি লগগুলির জন্য লগকটে একটি নির্দিষ্ট আকারের বাফার রয়েছে ( /dev/log/events) এবং এই সীমাটি 1024 বাইট। নন-বাইনারি লগগুলির জন্যও একটি সীমা রয়েছে:

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

সুতরাং বাইনারি এবং নন-বাইনারি উভয় লগের জন্য আসল বার্তার আকার 4040 ডলার বাইট। কার্নেল লগার ইন্টারফেসটি এই LOGGER_ENTRY_MAX_PAYLOADসীমাটি চাপিয়ে দেয় ।

লাইব্লগ উত্স (লগক্যাট দ্বারা ব্যবহৃত) এও বলে:

  • বার্তাটি কার্নেল লগ ড্রাইভার দ্বারা কাটা হয়েছে।

আমি আপনাকে এনএক্সলগ সরঞ্জামটি সুপারিশ করব যা লগক্যাট বাইনারি ব্যবহার করে না তবে কার্নেলের সীমাবদ্ধতার কারণে আমি সন্দেহ করি যে এটি আপনার সমস্যার সমাধান করবে। তবুও, এটি একটি চেষ্টা মূল্য হতে পারে। (অস্বীকৃতি: আমি লেখক।)


6
আমি এটি কোথায় পাই? এটি কি "লগক্যাট" কোডে রয়েছে? সুতরাং, আমি কি আমার নিজস্ব পরিবর্তিত লগক্যাটটি সংকলন করব?
d4Rk

4
বাইনারি / নন-বাইনারি লগ কি?
ফবিমাস্টার

4
মেটাডেটা ক্ষেত্রগুলি যুক্ত হওয়ার কারণে LOGGER_ENTRY_MAX_PAYLOAD, অ্যান্ড্রয়েডের আরও সাম্প্রতিক সংস্করণগুলিতে 4076 থেকে কমিয়ে 4068 করা হয়েছে ( এখানে দেখুন )।
মহিষ্মিত

89

ঠিক আছে, আকর্ষণীয়। উত্তরটি "আপনি সত্যিই এটি প্রসারিত করতে পারবেন না" তা দেখে আমি হতাশ হয়েছি। আমার প্রাথমিক চিন্তাটি ছিল এটি ভেঙে দেওয়া, যাতে আমি পুরো জিনিসটি দেখতে পারি, তাই এখানে আমি কীভাবে এটি করি তা আপনার সাথে ভাগ করে নিচ্ছি (এটি অভিনব কিছু নয় বা এটি দক্ষতার কাছাকাছি নয়, তবে এটি কাজটি একটি চিমটি হয়ে যায়):

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

শেষ স্ট্রিং দেখানোর জন্য সম্পাদিত!


সমস্যা নেই! আশা করি এটি আপনাকে সাহায্য করেছে
ট্র্যাভিস

আমি নিশ্চিত যে এখানে একটি ত্রুটি বন্ধ আছে। শেষ অংশটি পেতে আমাকে "i <চুনকাউন্ট +1" ব্যবহার করতে হয়েছিল
ড্যান

4
আপনি শেষ স্ট্রিংটি এতে হারিয়েছেন: int chunkCount = sb.length() / 4000;ব্যবহার int chunkCount = sb.length() / 4000; if (chunkCount * 4000 < sb.length()) chunkCount++;
টিমুর গিলফানভ

4
else { Log.v(TAG, sb); }বার্তাটি <= 4000 চর দীর্ঘ হলে লগ মুদ্রণ করতে যোগ করুন
বোজন রাদিভোজেভিচ বোম্বার

4
এই উত্তরটি ASCII বিহীন অক্ষরের জন্য ভুল। লগক্যাটটি ইউটিএফ 8 সমর্থন করে এবং সীমাটি 4k বাইট , অক্ষর নয়।
মাইগুয়েল

62

পুনরাবৃত্তভাবে এটি বেশ কয়েকটি টুকরো টুকরো টুকরো করে।

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

4
এটি এখন পর্যন্ত সবচেয়ে পরিষ্কার সমাধান এবং আমি প্রথমবারের মতো উত্পাদন কোডটিতে পুনরাবৃত্তিটি ব্যবহার করেছি।
আগ্রাসী

4
@ অ্যাগ্রেসার আপনি কেন উত্পাদনে 4000+ দীর্ঘ বার্তা লগ ইন করতে হবে?
TWiStErRob

4
আমার ব্যবহারের ক্ষেত্রে বড় জসন স্টাফ আউটপুট করা। ফাইলগুলি কেবল একটি ব্যথা।
মার্সেল ফ্যালিয়ের

4
খুব দরকারী ধন্যবাদ। আমি একটি উত্তর পোস্ট করেছি যা লাইনের শেষে স্ট্রিংটি ভেঙে দেয়।
ধাঁধা

4
দুর্দান্ত এবং সহজ সুন্দর ক্লিনার। তালি
মুহাম্মদ আশফাক


5

আমি যে কোডটি ব্যবহার করছি তা এখানে রয়েছে - এটি 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;
    }
}

4

নীচের কোডটি মার্ক বুয়েকিমা পোস্ট করেছেন তার সংশোধন is এটি নতুন লাইনে স্ট্রিং ভেঙে দেয়। দীর্ঘ 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);
    }
  }


2

আমাদের এই পেজিং যুক্তি

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

}

1

ট্র্যাভিসের সমাধানটি আমার নিজের করে দেওয়া,

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()আয় এড়ানোর hardcoding থেকে "4000" লিখিত বাইট সংখ্যা। তারপরে, বার্তা হিসাবে নিজেকে বার্তাটির অংশে কল করুন যা কিছুই না রেখে লগ করা যায় না।


দুর্ভাগ্যক্রমে, প্রিন্টলন # বাইট লিখিত এবং অক্ষরগুলিকে প্রদান করে = = বাইট।
gnuf

4
ভাল, এটি কাজ করে। আমি ধরে নিই কারণ আমি কেবল আসকি পাঠ্য লগ করছি।
জেফ্রি ব্লাটম্যান

1

যদি আপনার লগ খুব দীর্ঘ হয় (যেমন, ডিবাগিং কারণে আপনার ডাটাবেসের পুরো ডাম্প লগিং ইত্যাদি) এটি ঘটতে পারে যে লগক্যাট অতিরিক্ত লগিং প্রতিরোধ করে। এটির কাজ করার জন্য আপনি একটি টাইমআউট এভ্রি এক্স মিলিসেকেন্ড যুক্ত করতে পারেন।

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

সাবধান, কেবল এটি ডিবাগিং উদ্দেশ্যে ব্যবহার করুন কারণ এটি মুখ্য থ্রেডকে আটকাতে পারে।


1

LOGGER_ENTRY_MAX_PAYLOAD@ এমএএমএসমিথ যেমন উল্লেখ করেছেন, সাম্প্রতিক অ্যান্ড্রয়েড সংস্করণগুলিতে এটি 4068। তবে, আপনি যদি অন্য উত্তরে প্রদত্ত কোড স্নিপেটগুলিতে সর্বাধিক বার্তার দৈর্ঘ্য হিসাবে 4068 ব্যবহার করেন তবে বার্তাগুলি কেটে যাবে। এর কারণ অ্যান্ড্রয়েড আপনার বার্তার শুরু এবং শেষের দিকে আরও অক্ষর যুক্ত করেছে, এটিও গণনা করে। অন্যান্য উত্তরগুলি 4000 সীমাটি কার্যকারণ হিসাবে ব্যবহার করে। তবে, এই কোড দিয়ে সত্যই পুরো সীমাটি ব্যবহার করা সম্ভব (শ্রেণিটির নাম এবং লাইন নম্বরটি লগ হিসাবে চিহ্নিত করার জন্য কোডটি স্ট্যাক ট্রেস থেকে একটি ট্যাগ উত্পন্ন করে, এটি সংশোধন করতে নির্দ্বিধায়):

private static final int MAX_MESSAGE_LENGTH = 4068;

private enum LogType {
    debug,
    info,
    warning,
    error
}

private static void logMessage(LogType logType, @Nullable String message, @Nullable String tag) {
    logMessage(logType, message, tag, Thread.currentThread().getStackTrace()[4]);
}

private static void logMessage(LogType logType, @Nullable String message, @Nullable String customTag, StackTraceElement stackTraceElement) {
    // don't use expensive String.format
    String tag = "DASHBOARDS(" + stackTraceElement.getFileName() + "." + (!TextUtils.isEmpty(customTag) ? customTag : stackTraceElement.getMethodName()) + ":" + stackTraceElement.getLineNumber() + ")";
    int maxMessageLength = MAX_MESSAGE_LENGTH - (tag.length()) - 4; // minus four because android adds a letter showing the log type before the tag, e. g. "D/" for debug, and a colon and space are added behind it, i. e. ": "
    if (message == null || message.length() <= maxMessageLength) {
        logMessageInternal(logType, message, tag);
    } else {
        maxMessageLength -= 8; // we will add counter to the beginning of the message, e. g. "(12/15) "
        int totalChunks = (int) Math.ceil((float) message.length() / maxMessageLength);
        for (int i = 1; i <= totalChunks; i++) {
            int start = (i - 1) * maxMessageLength;
            logMessageInternal(logType, "(" + i + "/" + totalChunks + ") " + message.substring(start, Math.min(start + maxMessageLength, message.length())), tag);
        }
    }
}

private static void logMessageInternal(LogType logType, String message, String tag) {
    if (message == null) {
        message = "message is null";
    }
    switch (logType) {
        case debug:
            Log.d(tag, message);
            break;
        case info:
            Log.i(tag, message);
            break;
        case warning:
            Log.w(tag, message);
            break;
        case error:
            Log.e(tag, message);
    }
}

public static void d(String debug, String tag) {
    logMessage(LogType.debug, debug, tag);
}

0

লগক্যাটটির দৈর্ঘ্য বাড়ানোর কোনও বিকল্প আমি জানি না, তবে আমরা মূল লগ, ইভেন্ট লগ ইত্যাদির মতো বিভিন্ন লগগুলি খুঁজে পেতে পারি log লগ টার্মিনালে। পাথটি হ'ল: \ ডেটা \ লগার।


0

যদিও অন্যান্য প্রদত্ত সমাধানগুলি সহায়ক ছিল, তবুও আমি তাদের দ্বারা সন্তুষ্ট হইনি কারণ লগটি @ বি0ti দ্বারা উল্লিখিত LOGGER_ENTRY_MAX_LEN এর চেয়ে দ্বিগুণ দীর্ঘ হলে লগগুলি কেস কভার করে না। তদুপরি আমার নিম্নলিখিত সমাধানগুলিও সঠিক নয় কারণ LOGER_ENTRY_MAX_LEN গতিশীলভাবে পাওয়া যায় নি। কেউ যদি এটি করার কোনও উপায় জানেন তবে আমি মন্তব্যগুলি সম্পর্কে এটি শুনতে পছন্দ করব! যাইহোক, এই মুহূর্তে আমি আমার কোডে এই সমাধানটি ব্যবহার করি:

final int loggerEntryMaxLength = 4000;
int logLength = loggerEntryMaxLength - 2 - TAG.length();
int i = 0;
while (output.length() / logLength > i) {
    int startIndex = i++ * logLength;
    int endIndex = i * logLength;
    Log.d(TAG, output.substring(startIndex, endIndex));
}
int startIndex = i * logLength;
Log.d(
        TAG,
        output.substring(
                startIndex,
                startIndex + (output.length() % logLength)
        )
);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.