在程序中执行logcat命令获取日志

本文介绍了在Android开发中如何在程序运行时执行logcat命令获取日志,以应对生产环境中异常情况下的日志收集。讨论了logcat日志的缓存限制、权限问题以及两种抓取日志的方式:直接读取日志流和使用shell命令。对比了两种方式的优缺点,提供了ShellUtils工具类的相关信息。
摘要由CSDN通过智能技术生成

背景

在日常开发和调试过程中,我们经常需要用到logcat的日志来帮助我们定位问题,在生产环境也有类似的需求,当程序出现崩溃、anr等异常时,我们除了需要捕获异常日志外,往往需要抓取一段完整的logcat日志,给我们研发同学去分析定位问题,但是生产环境是复杂的,如果当发生异常后,设备很有可能被重启了,这时候我们的logcat日志往往就丢失了,无法事后再去抓取,所以这时候就需要我们在程序中提供一种自动抓取logcat日志的能力。

logcat的小知识点

  • 设备的logcat日志是有一个最大的缓存限制的,默认是256k,可以通过开发者选项去调整这个大小,也可以通过logcat -G 10M 设置。

  • 设备重启后,logcat的缓存会被清空。

  • 在终端中使用adb logcat命令获取log和在程序中调用logcat的命令获取log是两回事,获取到的日志信息往往是不同的,往往是在终端中获取的日志更全一些。

  • 自定义ROM修改默认的logcat缓存大小

// kernel\drivers\staging\android\logger.c
// 在create_log方法的第二个参数传入自动定义的大小就好
static int __init

logger_init(void) {
   
    int ret;
    ret = create_log(LOGGER_LOG_MAIN, 256 * 1024 );
    if (unlikely(ret))
        goto out;

    ret = create_log(LOGGER_LOG_EVENTS, 256 * 1024);
    if (unlikely(ret))
        goto out;

    ret = create_log(LOGGER_LOG_RADIO, 256 * 1024 );
    if (unlikely(ret))
        goto out;

    ret = create_log(LOGGER_LOG_SYSTEM, 256 * 1024);
    if (unlikely(ret))
        goto out;

    out:
    return ret;
}
  • 在程序中获取log需要加android.permission.READ_LOGS权限。

  • android 4.1之前版本通过申请READ_LOGS权限就可以读取其他应用的log了。但是谷歌发现这样存在安全风险,于是android 4.1以及之后版本,即使申请了READ_LOGS权限也无法读取其他应用的日志信息了。4.1版本中 Logcat的签名变为 “signature|system|development”了,这意味着只有系统签名的app或者root权限的app才能使用该权限。普通用户可以通过ADB查看所有日志。

  • 手机root后很多情况下也是无法在程序中使用root权限的,因为adb shell 的进程和程序执行的进程不是同一个,因此无法使用su命令。

抓取logcat的方式

方式一:读取日志流自己写入到文件中

private static boolean catchLogcatLog(String crashLogCatPath) {
   

        if(TextUtils.isEmpty(crashLogCatPath)){
   
            return false;
        }
        java.lang.Process logcatProcess = null;
        BufferedReader bufferedReader = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
   
            /** 获取系统logcat日志信息 */

            String[] running = new String[]{
   "logcat"};
            logcatProcess = Runtime.getRuntime().exec(running);

            bufferedReader = new BufferedReader(new InputStreamReader(
                    logcatProcess.getInputStream()));

            File file = new File(crashLogCatPath);
            File parentFile = file.getParentFile();
            if (!parentFile.exists() || !parentFile.isDirectory()) {
   
                parentFile.mkdirs();
            }
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file, true));

            String line;

            SimpleDateFormat simpleDateFormat = new 
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值