Logger 介绍使用

Logger 介绍

在日常开发中,日志是必不可少的一步,数据查看、bug 追踪、数据收集等都需要用到日志,Android 系统提供了 Log 类来实现,但是每次都要输入一个 TAG, 会非常的麻烦。所以你可以自己封装一个 Log 框架,也可以使用一些开源日志框架,比如:TimerXLogLogger 等,在这里主要介绍一下 Logger。

github.com/orhanobut

Logger 是 Orhan Obut 搞的, Simple, pretty and powerful logger for android.

Logger 支持多种类型:

String,String format,数组,集合,XML和JSON,同时也可将日志存储到文件,也可输出线程方法等详细信息

Logger 使用

1. Gradle 依赖:

implementation 'com.orhanobut:logger:2.2.0'

2. 添加 Adapter

Logger.addLogAdapter(new AndroidLogAdapter());

接下来就是可以直接使用了

Logger.d("message");



默认输出 Log 以及所在类名,方法名,行号,线程等相关信息。如果不想显示除 Log 外的其他信息,可以对 Adapter 进行相关设置,

FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
        .showThreadInfo(false)  // 展示线程信息
        .methodCount(5)         // 展示调用的方法个数,默认是 2
        .methodOffset(0)        // 跳过堆栈中的方法个数, 默认是 0
        .tag("My custom tag")   //  TAG 内容. 默认是 PRETTY_LOGGER
        .build();
Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy));

显示如下,如果 methodOffset 为1,则不展示 MainActivity.onCreate(),只显示其他 4 个。



如果需要将日志存储到本地文件,则需要使用 DiskLogAdapter, 同时需要声明存储权限,Logger 默认生成 csv 文件,存储在 /storage/emulated/0/logger 目录下,

Logger.addLogAdapter(new DiskLogAdapter());

如果针对不同的页面 Logger 的配置不同, 可以使用 Logger.clearLogAdapters(), 然后进行重新配置。

3. 其他类型

message 除了是 String 类型,还可以是集合,数组,

Logger.t("tag").e("Custom tag for only one use");

Logger.json("{ \"key\": 3, \"value\": something}");

Logger.d(Arrays.asList("foo", "bar"));

Logger.d(new int[]{2,3,19,4});

Logger.d("");

Map<String, String> map = new HashMap<>();
map.put("key", "value");
map.put("key1", "value2");

Logger.d(map);

Logger.d("message %s", " erro");

Logger 源码分析

1. 调用顺序

Logger 最终调用的还是 Log.println(int priority, String tag, String msg) 方法,以 Logger.d() 为例, 一步步查看

Logger.d("message");



指向 LoggerPrinter.d() 方法, 指向 log(), 由于可以同时添加多个 adapter, 所以在这里要进行一次 for 循环,遍历所有的 adapter







以 AndroidLogAdapter 为例,指向 AndroidLogAdapter 的 log() 方法, 最终使用系统 Log.println() 输出日志。





2. 存储分析

上传客户端日志,对于分析 app 运行情况可用户使用习惯是至关重要的一步,但是 Logger 的存储路径试固定的,没有提供相关的 api 进行设置,所以可以通过分析其中的原理,然后自定义一个 adapter. 对于这里的路径我建议存储在 /Android/data/包名, 因为此路径不需要获取用户权限,可以直接使用。

通过 new DiskLogAdapter(), 在其构造方法中 CsvFormatStrategy 使用 Builder 模式 创建了一个 CsvFormatStrategy 实例, 在 builder() 可以看到具体的路径,因为一旦在子线程中操作,Handler 需要手动启动 Looper, 所以这里 通过 HandlerThread 获取 Looper 传递给 Handler, 通过 DiskLogStrategy.WriteHandler 创建 Handler, 将将文件路径传递给 DiskLogStrategy.WriteHandler, 同时通过构造方法生成 DiskLogStrategy 对象,将 handler 传递给 DiskLogStrategy, 当输出 Log 时调用 DiskLogStrategy 的 log() 方法,通过 log() 方法中 handler 将 message 发送出去, 然后交给 handler 处理,存储到 DiskLogStrategy.WriteHandler 中的路径。










end

发布于 2021-06-11 19:34