adb logcat 如何针对应用包名进行过滤日志?

为何有这样的疑问?

1. adb logcat可以根据tag进行过滤日志。 例如 adb logcat -s “tag”, 但如果我想看到所有某个应用(如 cf.lihao.test )这个应用的所有日志, 如果不同过其他方法,则需要自己把所有的日志的标签全部设定为一样。

2. 奇怪的是, eclipse的logcat viewer是可以支持过滤包名, 输入cf.lihao.test 包名过滤, 则该应用下所有的日志,只要是该应用的相关日志,则全部可以根据需要打印出来。

为什么eclipse可以支持 app包名的进行过滤日志, 而adb logcat 不可以,只可以根据tag标签?

我们来分析看一下,

a) adb logcat -v long 通过-v long 参数,我们可以把每行日志的pid进程号输出。 即该日志是哪个进程的?
b) 我们通过adb shell ps 等命令可以查看到,哪个应用的pid是多少?
c) 然后通过程序,可以轻松的过滤出该应用下的所有日志,这样就非常方便debug了。

所以猜测,eclipse已经帮我们做了如上的实现。所以我们可以直接使用eclipse的logcat 插件, 或者自己写一个程序拉。

如下的代码, 编译后export 一个可执行jar后。 执行 java -jar logcat.jar “adb命令的路径” “com.xxx.xxx”

则com.xxx.xxx应用所有的日志则会全部打印出来了。

package cf.lihao.logcat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Logcat
{
  public static String adb;

  public static int getPidfromPs(String appPackage)
  {
    String s = null;
    try
    {
      Process logcat = Runtime.getRuntime().exec(adb + " shell ps");

      BufferedReader output = new BufferedReader(new InputStreamReader(logcat.getInputStream()));

      while ((s = output.readLine()) != null)
      {
        int ret = matchPid(".+?\\s+([0-9]+)\\s*.+" + appPackage, s);

        if (ret != -1) {
          return ret;
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    return -1;
  }

  public static void executeLogcatCommand(String command, String pid)
  {
    String s = null;
    boolean found = false;
    try
    {
      Process logcat = Runtime.getRuntime().exec(adb + " logcat -v long");

      BufferedReader output = new BufferedReader(new InputStreamReader(logcat.getInputStream()));

      System.out.println("starting output...");

      while ((s = output.readLine()) != null)
      {
        if ((!s.matches("^$")) && (!s.matches("^\\s*\n$")) && (!s.matches("^\\s$")) && (!s.matches("^\\s*\r\n$"))) {
          int ret = matchString("\\[\\s+.+\\s+.+\\s+([0-9]+):.+\\s+.+\\]", s, pid);
          if (ret == 1)
          {
            found = true;
            System.out.println(s);
          }
          else if ((found) && (ret == 3)) {
            System.out.println(s);
          }
          else if (ret == 2)
          {
            found = false;
          }
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  public static int matchString(String regex, String matchLine, String groupMatchLine)
  {
    Pattern pattern = Pattern.compile(regex);

    Matcher matcher = pattern.matcher(matchLine);

    if (matcher.find())
    {
      if ((groupMatchLine != null) && (groupMatchLine.equals(matcher.group(1)))) return 1;

      return 2;
    }

    return 3;
  }

  public static int matchPid(String regex, String matchLine)
  {
    Pattern pattern = Pattern.compile(regex);

    Matcher matcher = pattern.matcher(matchLine);

    if (matcher.find())
    {
      System.out.println("============found==============");
      System.out.print("Start index: " + matcher.start());
      System.out.print(" End index: " + matcher.end() + " ");
      System.out.println(matcher.group());
      System.out.println(matcher.group(1));
      return Integer.valueOf(matcher.group(1)).intValue();
    }

    return -1;
  }

  public static void main(String[] args)
  {
    adb = args[0];
    int pid = getPidfromPs(args[1]);
    System.out.println(args[0]);

    System.out.println("pid " + pid);

    if (pid != -1)
      executeLogcatCommand(args[0], String.valueOf(pid));
    else System.out.println("this app not found");
  }
}

此篇文章已被阅读6890 次

Add a Comment

邮箱地址不会被公开。 必填项已用*标注