我是靠谱客的博主 殷勤金毛,最近开发中收集的这篇文章主要介绍记录安卓系统日志保存成txt文件记录安卓系统日志设计自动化程序,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

记录安卓系统日志

背景:项目组里面的APP开发人员要求能够记录APP允许的系统日志。你要是主板连了串口调试线就简单了,终端里面一个logcat命令就行了,该过滤的过滤下。
使用 logcat 获取安卓的系统日志,当串口连上主板调试线的时候,在中断里面直接输入linux命令。
在这里插入图片描述
就是一个效果。
在这里插入图片描述

这里所谓的去日志就是把这些要的日志,保存成文本文件,然后拿出来分析。
思路:写一个程序,能够自动的运行 logcat ,并将截取到的信息输出 文本文件!!
当APP开发人员需要的时候,使用adb pull 去把日志文件下载下来。

设计自动化程序

这里晚点再来补充啊!

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include "gg_log.h"

#define		MAXBUF			1024
#define		LOGFILE			"/sdcard/gg/log/dlog.txt"
#define		PFILE			"/sdcard/gg/log/p.txt"
#define		MAXFILE			(50*1024*1024)

int main(int argc, char *argv[])
{
	int				n;
	char			buf[MAXBUF];
	int				len;
	int				fd[2], fdlog, fdp;
	int				i;
	long			location;
	//在linux内核中查找,其实就是 int类型
	pid_t			pid;

	//创建管道
	//当进程创建管道时,每次都需要提供两个文件描述符来操作管道。
	//其中一个对管道进行写操作,另一个对管道进行读操作。
	//参数数组包含pipe使用的两个文件的描述符。
	//fd[0]:读管道,fd[1]:写管道。
	if (pipe(fd) < 0) 
	{
		printf("pipe errorn");
		return -1;
	}
	//是创建一个新进程的唯一方式
	//当程序调用fork()函数并返回成功之后,程序就将变成两个进程,调用fork()者为父进程,后来生成者为子进程。
	if ((pid = fork()) < 0) 
	{	
		printf("fork errorn");
	} 
	else if (pid == 0) 
	{		//child
		write(fd[1], "hello worldn", 12);
		close(fd[0]);		//close read
		//用来复制一个现存的文件描述符,使两个文件描述符指向同一个file结构体
		//从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2)
		//0与进程的标准输入相关联,
		//1与进程的标准输出相关联,
		//2与进程的标准错误输出相关联
		dup2(fd[1], 0);
		dup2(fd[1], 1);
		dup2(fd[1], 2);
		if (fd[1] > 2)
			close(fd[1]);
/*		
		if (execlp("/system/bin/logcat", "-s", "ZHEGT", (char *)0) < 0) 
		{
			printf("child exec error!n");
			exit(1);
		} 
*/
		//相当于在终端里面输入命令
		if (system("logcat -s ZHEGT") < 0) 
		{
			printf("system error!n");
			exit(1);
		}
	}
	//parent
	close(fd[1]);		//close write

	//打开文件
	//fdlog 和 fdp,是两个文件描述符
	if (check_open_file(&fdlog, &fdp) < 0)
	{
		printf("check_open_file error!n");
		return -1;
	}
	//printf("flag1n");
	//获取的 location 是个什么东西呢?感觉是个地址,字符串数组地址
	//想明白了,这是获取文件的最后位置
	if ((location = get_location(&fdp)) < 0) 
	{
		if (location == -2) 
		{
			printf("init locationn");
			location = 0;
			//没有文件最后位置,表明是第一次,就设置文件位置
			if (set_location(&fdp, 0) < 0) 
			{
				printf("set location errorn");
				return -1;
			}
		}
		else 
		{
			printf("get_location error!n");
			return -1;
		}
	}

	//定位到文件最后的位置
	if (lseek(fdlog, location, SEEK_SET) < 0) 
	{
		printf("lseek error!n");
		return -1;
	}
	
	//进入死循环
	while(1)
	{
		if ((len = read(fd[0], buf, MAXBUF)) < 0) 
		{
			printf("read error!n");
			return -1;
		}
		else 
		{
			if (len > 0) 
			{
				location += len;
				printf("len=%d, location=%ldn", len, location);
				if (location >= MAXFILE) 
				{
					location -= len;
					for (i = 0;i <= (MAXFILE - location); i++ )
					{
						if (write(fdlog, "*", 1) < 0) 
						{
							printf("write error1!n");
							return -1;
						}
					}
					location = len;
					if (lseek(fdlog, 0, SEEK_SET) < 0) 
					{
						printf("lseek error!n");
						return -1;
					}
				}
				if (write(fdlog, buf, len) < 0) 
				{
					printf("write error2!n");
					return -1;
				}
				for (i = 0; i < 5; i++) 
				{
					if (write(fdlog, "n", 1) < 0) 
					{
						printf("write error3");
						return -1;
					}
				}
				if (lseek(fdlog, -5, SEEK_CUR) < 0) 
				{
					printf("lseek error!");
					return -1;
				}
				if (set_location(&fdp, location) < 0) 
				{
					printf("set location errorn");
					return -1;
				}
			}
			else 
			{
				printf("sleep 5s");
				sleep(5);
			}
		}
	}

	exit(0);
}

//检测能否成功打开日志文件
int check_open_file(int *fdlog, int *fdp)
{
	//创建文件 "/sdcard/gg/log/dlog.txt" 
	//不存在就创建,存在就打开
	if (access(LOGFILE, F_OK) < 0)
	{
		printf("logfile does not exist! create it!n");
		if ( (*fdlog = open(LOGFILE, O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR)) < 0) 
		{
			printf("create logfile failed!n");
			return -1;
		}
	}
	else 
	{
		if ((*fdlog = open(LOGFILE, O_WRONLY | O_SYNC)) < 0)
		{
			printf("open logfile error!n");
			return -1;
		}
	}
	
	//创建文件 "/sdcard/gg/log/p.txt"
	//不存在就创建,存在就打开
	if (access(PFILE, F_OK) < 0)
	{
		printf("pfile does not exist! create it!n");
		if ( (*fdp = open(PFILE, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | O_SYNC)) < 0)
		{
			printf("create pfile failed!n");
			return -1;
		}
	}
	else
	{
		if ((*fdp = open(PFILE, O_RDWR | O_SYNC)) < 0)
		{
			printf("open pfile error!n");
			return -1;
		}
	}
	return 0;
}

long get_location(int *fdp)
{
	char			buf[20];
	long			location;

	//返回值为实际读取到的字节数
	if (read(*fdp, buf, 10) != 10)
	{
		printf("empty pfile, need to init!n");
		return -2;
	}
	//字符产最后一位赋值
	buf[10] =0;		//set to null

	return(atol(buf));
}

int set_location(int *fdp, long location)
{
	char			buf[20];
	
	//构造buf字符串
	if (snprintf(buf, 20, "%010ld", location) < 0)
	{
		printf("snprintf error!n");
		return -1;
	}
	if (strlen(buf) != 10)
	{
		printf("length != 10n");
		return -1;
	}
	//lseek函数将文件指针移动后,那么再去read/write时就是从移动过后的位置开始的了
	if (lseek(*fdp, 0, SEEK_SET) < 0)
	{
		printf("lseek error!n");
		return -1;
	}
	if (write(*fdp, buf, 10) != 10)
	{
		printf("write location error!n");
		return -1;
	}

	return 0;
}

实现效果

这个程序运行之后,会把系统日志全部存储在 /sdcard/gg/log/dlog.txt 中,之后就是各种办法下载下来就是了,可以直接SD卡拷贝,也可以adb 工具下载!

最后

以上就是殷勤金毛为你收集整理的记录安卓系统日志保存成txt文件记录安卓系统日志设计自动化程序的全部内容,希望文章能够帮你解决记录安卓系统日志保存成txt文件记录安卓系统日志设计自动化程序所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部