Android开发规范:日志Log

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ddnosh/article/details/84574121


Log对于开发者定位问题来说是一个必不可少的工具。开发人员需要通过Log提供的信息,比如Crash异常,能够定位异常类型以及异常的发生代码位置;或者查看输出的内容是否达到期望;亦或者通过Log提供的信息能够看到整个信息的交互流程。
因此拥有一个快捷便利有效的Log输出工具是整个项目必不可少的一部分。

1. 现有的系统Log

2018-11-27 20:50:00.614 29110-29110/com.demo D/ActivityThread: Added TimaKeyStore provider
格式:timestamp PID TID log-level log-tag

timestamp PID TID package name log-level log-tag
时间戳 进程id 线程id 包名 日志类型 日志tag

2. 改进的Log工具

系统提供的日志虽然已经具备了基本的信息,但是我们可以改进现有的Log功能。
比如提供Log打印类名、方法名、行数。
这样我们直接Ctrl + L输入行数就可以跳转到Log输出的位置,加快问题定位速度。

public class LogUtil {
    public static String customTagPrefix = "ddnosh";
    private static final boolean isDebug=true;

    private LogUtil() {
    }

    private static String generateTag() {
        StackTraceElement caller = new Throwable().getStackTrace()[2];
        String tag = "%s.%s(Line:%d)";
        String callerClazzName = caller.getClassName();
        callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
        tag = String.format(tag, callerClazzName, caller.getMethodName(), caller.getLineNumber());
        tag = TextUtils.isEmpty(customTagPrefix) ? tag : customTagPrefix + ":" + tag;
        return tag;
    }

    public static void d(String content) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.d(tag, content);
    }

    public static void d(String content, Throwable tr) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.d(tag, content, tr);
    }

    public static void e(String content) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.e(tag, content);
    }

    public static void e(String content, Throwable tr) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.e(tag, content, tr);
    }

    public static void i(String content) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.i(tag, content);
    }

    public static void i(String content, Throwable tr) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.i(tag, content, tr);
    }

    public static void v(String content) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.v(tag, content);
    }

    public static void v(String content, Throwable tr) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.v(tag, content, tr);
    }

    public static void w(String content) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.w(tag, content);
    }

    public static void w(String content, Throwable tr) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.w(tag, content, tr);
    }

    public static void w(Throwable tr) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.w(tag, tr);
    }


    public static void wtf(String content) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.wtf(tag, content);
    }

    public static void wtf(String content, Throwable tr) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.wtf(tag, content, tr);
    }

    public static void wtf(Throwable tr) {
        if (!isDebug) return;
        String tag = generateTag();

        Log.wtf(tag, tr);
    }

}

3. 从日志模块谈扩展性

日志作为一个基础模块功能,应当具备良好的扩展性。

所谓的扩展性,比如市面上有很多第三方日志工具,比如Log4J, Logger,Logback等,很多项目都会选择其中一个作为项目的日志模块,或者一个团队的多个项目都用一套固定的日志模块。

但是从通用性的角度考虑,Project应该和Module减少耦合性,也就是说一个Project可以在任何时候都能随时随地更换Module,而不需要更改Project中的代码,通过配置文件进行动态更新。

比如我们又找到了一个性能更好的Log系统,能够提升日志打印、保存效率,并且还有更详细的打印日志,那么我们该怎么替换呢?那是不是要到Project里面一个个的将旧的API接口替换成新的API接口呢?

那这样的来说,Project其实是和某一个Module的API强耦合了。

这有点像电脑的USB接口,我们需要外接存储设备,那么USB接口就是一个连接电脑和外置存储设备之间的桥梁,我们可以插入优盘,如果觉得容量小了,那么我们可以拔掉优盘,插上外置的移动硬盘,然后电脑本身不需要做任何改动,就可以用上外置的移动硬盘。
这里,电脑 = Project,USB = 协议,外置设备(优盘、移动硬盘) = Module

在《阿里巴巴Java开发手册》里面有对Log接入的明确规定:
( ( 二) ) 日志规约
1.【强制】应用中不可直接使用日志系统 (Log 4 j 、 Logback) 中的 API ,而应依赖使用日志框架
SLF4J 中的 API ,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);

LoggerFactory其实就是一个工厂模式中的对象,我们后续会针对利用工厂模式解除Project和Module之间的耦合性做专门的讲解。

猜你喜欢

转载自blog.csdn.net/ddnosh/article/details/84574121