概述
记录安卓系统日志
背景:项目组里面的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文件记录安卓系统日志设计自动化程序所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复