-
有这么一个场景
万恶的测试人员,总是爱找我们的茬,每次一出问题就拿手机过来,尼玛,什么东西麻,一堆bug,还让不让人下班。然后呢没办法啰,测试就是上帝,你就只好拿他的手机过来找日志啰,尼玛,日志出来一大堆,还要滚到最后才能看到最新的错误信息,这时间也浪费得够可以的了。。。百万只草泥马飘过。。。还有一大堆bug要修复呢,年纪轻轻的,我还不想被拉去祭天,怎么办。。。
duang...duang... 这个log日志神器就这样出天上掉下来了。。。
可以设置每个log的文件大小有木有。。。
可以格式化输出漂亮的样式的log有木有。。。
可以把最新的错误信息在文件最前面显示有木有。。。
足不出户就可以在内网上查看手机上面的log有木有。。。
真的是神器,有木有。。。
现在已躺在github有木有。。。
欢迎收看我的博客有木有。。。
欢迎使用 FastAndrUtils android快速开发工具类有木有。。。
广告买多了。。。不好意思。。。现在进入正题
-
功能列表
- 可设置Log的开启和关闭
- 可自定义Log的Tag
- 可设置log保存的文件大小
- 可设置是否保存log到sd卡
- log以html格式保存,且带html样式,查看更直观方便
- 可显示当前log的包名,类名,及行号,可点击行号跳转
- log保存可以实现头部数据插入,显示最新的log在最前面查看log更方便
- log带边框输出,查看更直观
- 可内网通过浏览器查看log数据
-
有图有真相
-
功能实现
由于code不少,就不贴完整代码,就找些关键的来写。完整代码可到github观看。
- log的基本配置
/**
* 是否开启bebug模式
*/
public FLogUtils debug(boolean debug) {
...
}
/**
* 是否保存到sd卡
*/
public FLogUtils saveSD(boolean savesd) {
...
}
/**
* 设置log文件大小
*/
public FLogUtils setLogSize(int logSize) {
...
}
/**
* 设置log文件目录
*/
public FLogUtils setlogDir(String logDir) {
...
}
- log日志输出
//默认tag日志输出
public void e(String msg) {
e("www.hotapk.cn", msg);
}
//自定义日志输出
public void e(String tag, String msg) {
...
}
- 获取log的当前所在的类及行数
private String targetStackTraceMSg() {
StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
if (targetStackTraceElement != null) {
return "at " + targetStackTraceElement.getClassName() + "." + targetStackTraceElement.getMethodName() +
"(" + targetStackTraceElement.getFileName() + ":" + targetStackTraceElement.getLineNumber() + ")";
} else {
return "";
}
}
private StackTraceElement getTargetStackTraceElement() {
StackTraceElement targetStackTrace = null;
boolean shouldTrace = false;
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
boolean isLogMethod = stackTraceElement.getClassName().equals(FLogUtils.class.getName());
if (shouldTrace && !isLogMethod) {
targetStackTrace = stackTraceElement;
break;
}
shouldTrace = isLogMethod;
}
return targetStackTrace;
}
- log保存到sd卡
/**
* 追加数据
*
* @param filePath
* @param content
* @param header 是否在头部追加数据
*/
public static void appendText(String filePath, String content, boolean header) {
RandomAccessFile raf = null;
FileOutputStream tmpOut = null;
FileInputStream tmpIn = null;
try {
File tmp = File.createTempFile("tmp", null);
tmp.deleteOnExit();//在JVM退出时删除
raf = new RandomAccessFile(filePath, "rw");
//创建一个临时文件夹来保存插入点后的数据
tmpOut = new FileOutputStream(tmp);
tmpIn = new FileInputStream(tmp);
long fileLength = 0;
if (!header) {
fileLength = raf.length();
}
raf.seek(fileLength);
/**将插入点后的内容读入临时文件夹**/
byte[] buff = new byte[1024];
//用于保存临时读取的字节数
int hasRead = 0;
//循环读取插入点后的内容
while ((hasRead = raf.read(buff)) > 0) {
// 将读取的数据写入临时文件中
tmpOut.write(buff, 0, hasRead);
}
//插入需要指定添加的数据
raf.seek(fileLength);//返回原来的插入处
//追加需要追加的内容
raf.write(content.getBytes());
//最后追加临时文件中的内容
while ((hasRead = tmpIn.read(buff)) > 0) {
raf.write(buff, 0, hasRead);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (tmpOut!=null){
try {
tmpOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (tmpIn!=null){
try {
tmpIn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (raf!=null){
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
以上就是实现了基本自定义的log的造轮子功能
以下内容才是我这log工具类的关键。。。
让你的log日志可以在内网访问
- 使用鼎鼎有名的 nanohttpd 类 ,这样就可以把android当内网服务器来使用了
- 继承NanoHTTPD类
public class LogNetServer extends NanoHTTPD {
private Context context;
public LogNetServer(int port) {
super(port);
}
public LogNetServer(String hostname, int port) {
super(hostname, port);
}
public LogNetServer(int port, Context context) {
super(port);
this.context = context;
}
@Override
public Response serve(IHTTPSession session) {
String file_name = session.getUri().substring(1);
StringBuffer br = new StringBuffer();
String header = FAssetsARawUtils.getAssetsToString("baidu.html", context);
br.append(header);
String filedir = FLogUtils.getInstance().getLogFileDir();
FLogUtils.getInstance().e("测试下效果-----");
if (file_name.isEmpty()) {
File[] files = FFileUtils.getFiles(filedir);
if (files != null) {
for (int i = 0; i < files.length; i++) {
br.append(
"<div class=\"exp\"><a href = "
+ "/log?logfile="
+ files[i].getName() +
" target=\"_blank\" >" + files[i].getName() +
"</a ></div>"
);
}
}
} else {
Map<String, String> parms = session.getParms();
if (parms.containsKey("logfile")) {
String name = parms.get("logfile");
String logstr = FFileUtils.readFile(filedir + "/" + name);
br.append(logstr);
} else {
br.append("有问题");
}
}
br.append("</body></html>");
return newFixedLengthResponse(Response.Status.OK, "text/html", br.toString());
}
}
- FLogUtils 创建启动和关闭WebServer服务方法
/**
* 启动log的WebServer服务
*
* @param port
* @param context
*/
public void startLogServer(int port, Context context) {
if (testHttpd == null) {
synchronized (FLogUtils.class) {
if (testHttpd == null) {
testHttpd = new LogNetServer(port, context.getApplicationContext());
}
}
}
try {
testHttpd.start();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 关闭log的WebServer服务
*/
public void stopLogServer() {
if (testHttpd != null && testHttpd.isAlive()) {
testHttpd.stop();
}
}
- 还有一个html文件
<!Doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>less code , less bug</title>
<style type="text/css">
.dotted {border-style: dotted;
margin-top: 36px;}
.exp{ border-bottom:1px dashed #F00}
div {padding: 10px;}
.redcolor{ color:#F00;}
</style>
</head>
<body>
啰嗦了半天终于写完了这篇log工具类的文章,文采不好,莫见怪。。。
看完整代码请移步github
网友评论