--------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