Android-Tool[shell]: 复现指定crashlog抓取日志文件脚本

--------2019.4.23 update--------------
使用方法:

连接手机直接在电脑终端运行脚本即可:

./as_logcat_offline_4.22.sh

(电脑终端上运行脚本脚本会自动push自身至手机中并以nohup方式运行push至手机中的脚本)

#!/bin/bash
# 20190401 by [email protected]
TEMP_LOG_DIR=/data/local/log/
TEMP_LOGFILE=$TEMP_LOG_DIR"as_logcat_crash"
TARGET_KEY_LOG="com.example.chengang.myapplication"
TARGET_LOG_BACKUP_DIR=/sdcard/MIUI/as_target_log/
DUT_SHELL_PID=-1

DUT_SHELL_PID
#手机返回 0 ,电脑返回 1
echo "aaaa1=$?"

is_dut_or_com(){
    env_str=$( printenv | grep "SHELL=")
    if [[ $env_str == "SHELL=/system/bin/sh" ]]; then
        echo "DUT"
        return 0
    elif [[ $env_str == "SHELL=/bin/bash" ]];then
        echo "COM"
        return 1
    else
        echo "OTHER"
        return 2
    fi
}

push_script(){
    check_if_can_push
    target_file="/system/bin/logcat_crash.sh"
    adb push $1 $target_file && adb shell chmod a+x $target_file
    # nohup 启动push至设备中的脚本,终端运行后拔掉useb线设备中的脚本可以继续运行
    adb shell nohup sh $target_file
}

check_if_can_push(){
    check_root=`adb root`
    check_root=`adb root`
    if [[ $check_root != "adbd is already running as root" ]];then
        echo $check_root
        exit -1
    else
        echo "check adb root ok"
        check_disable_verity=`adb disable-verity`
        if [[ $check_disable_verity=="verity is already disabled" ]];then
            check_remount=`adb remount`
            if [[ $check_remount != "remount succeeded" ]]; then
                echo "remount failed!"
                exit -1
            fi
        else
            echo $check_disable_verity
            exit -1
        fi
    fi
}

# 清除crash log
dut_clear_crash_log(){

    clear_all_result=`logcat -b all -c`
    clear_result=`logcat -b crash -c`
    echo "clear result : $clear_result"
    while [[ $clear_result != "" ]]
    do
        echo "offline log clear failed need redo!"
        clear_result=`logcat -b crash -c`
    done
    echo "offline log clear crash log successed!"
}

# 清除重复的老进程
dut_clear_old_process(){
    # 防止重启产生多个进程
    echo "start check dup proc"
    #找上一个sh /system/bin/logcat_crash.sh进程,杀掉其及其子进程
    result=`ps -ef | grep "logcat_crash.sh"`
    echo "-start---------->\n $result"
    echo "-end---------->\n "
    echo "self proc : $$"
    # 本shell进程的pid
    DUT_SHELL_PID=$$
    echo "$result"| while read line
    do
        echo "line: $line"
        pid_shell=`echo $line|awk -F ' ' '{print $2}'`
        ppid_shell=`echo $line|awk -F ' ' '{print $3}'`
        echo "pid = $pid_shell ,ppid = $ppid_shell this proc pid = $$"
        if [[ "$pid_shell" != $$ ]];then
            #当前shell进程的pid为 $$
            if [[ "$ppid_shell" != $$ ]];then
                echo "ppid is not this pid $pid_shell ,ppid $ppid_shell, tpid $$"
                # kill -9 -pid 杀掉老进程及其子进程
                kill -9 -$pid_shell
            else
                result=`ps -ef | grep "logcat"`
                echo "-start---------->\n $result"
                echo "-end---------->\n "
            fi
        else
            echo "self proc : $$"
        fi
    done
}

dut_backup_logcat(){
    date_str=`date +%Y_%m_%d_%H_%M`
    echo $date_str
    mkdir -p $TARGET_LOG_BACKUP_DIR$date_str/
    mv $TEMP_LOG_DIR* $TARGET_LOG_BACKUP_DIR$date_str/
    echo "offline log backup crash info finished"
}

dut_promote_proc_adj(){
    # 防止lowmemkiller杀掉
    result=`ps -ef | grep "logcat_crash.sh"`
    echo "***************:\n $result"
    echo "***************."
    #按照空格分割字串,取第2个就是pid print $2
    logcat_pid=`echo $result|awk -F ' ' '{print $2}'`
    echo "offline log logcat $logcat_pid"
    adj1=`cat /proc/$logcat_pid/oom_score_adj`
    echo "offline log before set prority: adj:$adj1"
    echo -999>/proc/$logcat_pid/oom_score_adj
    adj2=`cat /proc/$logcat_pid/oom_score_adj`
    echo "offline log after set prority: adj:$adj2"
    #设置shell进程oom_score_adj,该shell进程之后创建的子进程也将继承
}

dut_do_logcat(){
    dut_clear_crash_log
    dut_clear_old_process
    dut_promote_proc_adj
    mkdir -p $TEMP_LOG_DIR
    /system/bin/logcat -r 8096 -n 10 -b all -f$TEMP_LOGFILE &
    sleep 2s

    result=`ps -ef | grep "logcat"`

    echo "offline log monitor start!"

    logcat -b crash| while read line
    do
        echo "$line"
        result=$(echo "$line" | grep $TARGET_KEY_LOG)
        if [[ "$result" != "" ]];then
            echo "offline log finished : $result"
            sleep 5s
            dut_backup_logcat
            kill DUT_SHELL_PID
            echo "offline log backup log and clear the shell"
            exit 0
        fi
    done
}

is_dut_or_com
result=$?
if [ $result -eq 0 ];then
    dut_do_logcat
elif [ $result -eq 1 ];then
    push_script $0
fi

--------old version---------------

有时候log容易被冲掉,比如camera的camxlog,极容易被冲掉,迟个几十秒抓bugreport就有可能抓不到需要的logcat了
需要一直抓取logcat,复现了问题就把logcat的保存起来,
所以需求如下:
1.需要不断的抓取logcat
2.复现指定问题保存日志文件
简单试下如下,匹配规则还可以再完善下,日后再更新

adb push  ./as_logcat_offline.sh system/bin/

adb shell chmod a+x system/bin/as_logcat_offline

adb shell sh system/bin/as_logcat_offline &

shell 脚本如下

umask 022

TEMP_LOG_DIR=/data/local/log/
TEMP_LOGFILE=$LOGDIR"/logcatlog"
CRASH_KEY_WORD="com.example.chengang.myapplication"
TARGET_LOG_BACKUP_DIR=/sdcard/MIUI/crash_log/
echo "offline log start!!!"

#/system/bin/logcat -r 8096 -n 64 -v threadtime -f $LOGFILE

#清除crash log
clear_result=`logcat -b crash -c`
while("$clear_result" != "")
do
    echo "offline log clear failed need redo!"
    clear_result=`logcat -b crash -c`
done
echo "offline log clear crash log successed!"

# 防止重启产生多个进程
echo "start check dup proc"
result=`ps -ef | grep "as_logcat_offline.sh"` 
echo "$result"| while read line
do
    echo $line
    pid_shell=`echo $line|awk -F ' ' '{print $2}'`
    ppid_shell=`echo $line|awk -F ' ' '{print $3}'`
    echo "pid = $pid_shell ,ppid = $ppid_shell this proc pid = $$"
    if [[ "$pid_shell" != $$ ]];then
        echo "dup old proc"
        if [[ "$ppid_shell" != $$ ]];then
            echo "ppid is not this pid $pid_shell ,ppid $ppid_shell, tpid $$"
            #杀掉老进程及其子进程
            kill -9 -$pid_shell
        else
            echo "this proc is the child proc ,dismis"
        fi
    else 
        echo "self proc : $$"
    fi
done

mkdir -p $TEMP_LOG_DIR
# 保存10份日志,每个日志大小8096kb
/system/bin/logcat -r 8096 -n 10 -v threadtime -f $TEMP_LOGFILE &

sleep 2s
#复现了问题后将logcat保存至其他目录
backup_logcat(){
    date_str=`date +%Y_%m_%d_%H_%M`
    echo $date_str
    mkdir -p $TARGET_LOG_BACKUP_DIR$date_str/
    mv $TEMP_LOG_DIR* $TARGET_LOG_BACKUP_DIR$date_str/
    echo "offline log backup crash info finished"
}

# 防止lowmemkiller杀掉
result=`ps -ef | grep "logcatlog"`
echo $result
#按照空格分割字串,取第2个就是pid print $2
logcat_pid=`echo $result|awk -F ' ' '{print $2}'`
echo "offline log logcat $logcat_pid"
adj1=`cat /proc/$logcat_pid/oom_score_adj`
echo "offline log before set prority: adj:$adj1"
echo -999>/proc/$logcat_pid/oom_score_adj
adj2=`cat /proc/$logcat_pid/oom_score_adj`
echo "offline log after set prority: adj:$adj2"

echo "offline log monitor start!"
logcat -b crash | while read line
do
    result=$(echo "$line" | grep $CRASH_KEY_WORD)
    if [[ "$result" != "" ]];then
        echo "offline log finished : $result"
        backup_logcat
        kill logcat_pid
        echo "offline log backup log and clear the shell"
        exit 0
    fi
done

你可能感兴趣的:(tools)