打造不一样的android log日志类

打造不一样的android log日志类

image.png

  • ##有这么一个场景
    >万恶的测试人员,总是爱找我们的茬,每次一出问题就拿手机过来,尼玛,什么东西麻,一堆bug,还让不让人下班。然后呢没办法啰,测试就是上帝,你就只好拿他的手机过来找日志啰,尼玛,日志出来一大堆,还要滚到最后才能看到最新的错误信息,这时间也浪费得够可以的了。。。百万只草泥马飘过。。。还有一大堆bug要修复呢,年纪轻轻的,我还不想被拉去祭天,怎么办。。。
    duang…duang… 这个log日志神器就这样出天上掉下来了。。。
    可以设置每个log的文件大小有木有。。。
    可以格式化输出漂亮的样式的log有木有。。。
    可以把最新的错误信息在文件最前面显示有木有。。。
    足不出户就可以在内网上查看手机上面的log有木有。。。
    真的是神器,有木有。。。
    现在已躺在github有木有。。。
    欢迎收看我的博客有木有。。。
    欢迎使用 FastAndrUtils android快速开发工具类有木有。。。

广告买多了。。。不好意思。。。现在进入正题

  • ## 功能列表
  1. 可设置Log的开启和关闭
  2. 可自定义Log的Tag
  3. 可设置log保存的文件大小
  4. 可设置是否保存log到sd卡
  5. log以html格式保存,且带html样式,查看更直观方便
  6. 可显示当前log的包名,类名,及行号,可点击行号跳转
  7. log保存可以实现头部数据插入,显示最新的log在最前面查看log更方便
  8. log带边框输出,查看更直观
  9. 可内网通过浏览器查看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日志可以在内网访问

  1. 使用鼎鼎有名的 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

发表评论

电子邮件地址不会被公开。 必填项已用*标注