远程运行日志调试

安卓在当前进程直接使用log存运行日志会有两个问题

  • 多少有点耗时,打印的日志需要实时存到文件
  • 当前进程异常退出可能会出现日志丢失的情况

解决方法最好是新建一个服务,执行命令  logcat -f file -v threadtime tag:v *:s,这里过滤方式最好使用tag,不要用grep,后者是输出日志后过滤,依然会存到文件里,造成大量无效信息!

通常app这边有测试环境和生产环境,测试环境可以只过滤http的,生产环境再输出全部日志;测试环境的时候开发可以看到全部日志的,但是测试组通常只关心请求日志~

(附日志服务代码:设置了过滤、文件大小限制等) 存好日志文件可以通过静默推送或者用户手动拉回就可以咯

public class LogRecordService extends Service {
	private static final String TAG = LogRecordService.class.getSimpleName();

	private static final String ACTION = "action";

	Timer timer;
	Process process;
	String logFile;

	private void execLogcatCmd() {
		List<String> commandList = new ArrayList<>();
		commandList.add("logcat");
		commandList.add("-c");
		// 先清除日志
		try {
			Runtime.getRuntime().exec(
					commandList.toArray(new String[commandList.size()]));
		} catch (Exception e1) {
			ZNLog.printStacktrace(e1);
		}
		//测试环境只存 http请求, 正式环境存所有的log
		String tagGrep = EnvConfig.isDebug()? ZNHttpLogInterceptor.TAG:ZNLog.TAG;
		//测试环境只看http,正式环境打印所有log
		commandList.clear();
		commandList.add("logcat");
		commandList.add("-f");
		commandList.add(logFile);
		commandList.add("-v");
		commandList.add("threadtime");
		commandList.add(tagGrep+":v");
		commandList.add("*:S");
		try {
			String[] comms = commandList
					.toArray(new String[commandList.size()]);
			process = Runtime.getRuntime().exec(comms);
			ZNLog.e(TAG, "writeLog command: " + Arrays.deepToString(comms));
		} catch (Exception e) {
			ZNLog.printStacktrace(e);
		}
	}

	/**
	 * 日志文件超过一定大小
	 * @return
	 */
	private boolean isLogOverMax(){
		ZNLog.d(TAG, "isLogOverMax() called : " + "");
		if(TextUtils.isEmpty(logFile)){
			return false;
		}
		File file = FileUtils.getFileByPath(logFile);
		if(!file.exists()){
			return false;
		}
		double size = (file.length()/(1024.0*1024.0));
		ZNLog.d(TAG, "isLogOverMax() called : space = " + size);
		return size>3;//大于3m
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		if(timer!=null){
			timer.cancel();
		}
		timer = null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if(intent!=null&&intent.getExtras()!=null){
			int action = intent.getIntExtra(ACTION,1);
			if(action!=1){
				onStopCmd(true);
			}else{
				onStartCmd();
			}
		}
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	private void onStartCmd(){
		ZNLog.e(TAG, "开启日志记录服务...");
		onStopCmd(false);
		timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				if(timer==null){
					return;
				}
				ZNLog.d(TAG, "run() called : logFile==null " + (logFile==null));
				if(TextUtils.isEmpty(logFile)){
					logFile = LogFileHelp.getLastFilePath();
					if(!FileUtil.isFileExist(logFile)||isLogOverMax()){//文件不存在或如果超过了容量
						logFile = LogFileHelp.getNewLogFilePath();
					}
					execLogcatCmd();
				}else{
					if(isLogOverMax()){//再次循环的时候,如果超过了容量
						if(!ZNApplication.isDebugMode()){
							//正式环境一旦超过容量,就停掉日志记录(也就是说只会记录一个文件,留作上传使用)
							onStopCmd(true);
							return;
						}
						logFile = LogFileHelp.getNewLogFilePath();
						execLogcatCmd();
					}
				}
			}
		},100,5*60*1000);//5分钟检测一次
	}

	private void onStopCmd(boolean stopServer) {
		if(timer!=null){
			timer.cancel();
		}
		timer = null;
		try {
			if(process!=null){
                process.destroy();
				process = null;
            }
		} catch (Exception e) {
			e.printStackTrace();
		}
		logFile = null;
		if(stopServer){
			stopSelf();
		}
	}

	//开始
	public static void startService(){
		Intent intent = new Intent(ZNApplication.getZNContext(), LogRecordService.class);
		intent.putExtra(ACTION,1);
		ZNApplication.getZNContext().startService(intent);
	}

	//停止
	public static void stopService(){
		Intent intent = new Intent(ZNApplication.getZNContext(), LogRecordService.class);
		intent.putExtra(ACTION,0);
		ZNApplication.getZNContext().startService(intent);
	}
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值