安卓to鸿蒙系列:Logger 原创 精华
目录
Guide
本文基于https://gitee.com/openharmony-tpc/logger 分析Logger的源码,及移植到鸿蒙需要做的工作。
在安卓to鸿蒙系列:Timber 里我就已经提到,我喜欢Logger和Timber一起使用。原因很简单,因为Timber接口简洁,Logger的输出样式好看。
常规套路:
Logger源码分析
Timber只有一个文件,600多行代码,Logger相对复杂一些,不过结构也一样简单,很容易读懂源码。和Timber一样,Logger的扩展性也一样优秀。
Timber内置了DebugTree(在控制台输出日志)。Logger内置了AndroidLogAdapter
(控制台输出)、DiskLogAdapter
(输出日志到本地磁盘)
先看图,有一个整体的认识:
解释一下上面的图:
-
Logger 也使用了 委托(delegate)模式,Logger把所以的操作都委托给了
Printer printer
-
Printer 是日志能力的抽像(即,定义了日志工具的api),类似于Timber中的Tree。定义的api有:
-
日志相关api:
v()
、d()
、i()
、e()
、wtf()
,以及xml()
、json()
对xml、json数据格式的支持。 -
设置临时tag:
t()
-
LogAdapter相关api:
addAdapter(LogAdapter adapter)
、clearLogAdapters()
Printer
的默认实现是LoggerPrinter
,我们可以自定义自己的实现。不过,多数情况下貌似没必要。 -
-
与Timber相比,Logger对Timber中的Tree进一步抽像。以 LogAdapter 适配不同的日志能力,如Android控制台输出(
AndroidLogAdapter
)、保存到磁盘(DiskLogAdapter
)。从类名上,我们也能看出用了适配器(apapter)模式
当然我们也可以定义鸿蒙HiLog控制台输出的LogAdapter(取个名字:
HarmonyLogAdapter
) -
FormatStrategy 格式化原始数据,决定了LogAdapter输出日志的样式。
AndroidLogAdapter
中的默认实现是PrettyFormatStrategy
(可以显示线程信息、统一的tag:"PRETTY_LOGGER"
、线程栈);DiskLogAdapter
中的默认实现是CsvFormatStrategy
(csv文件的格式); -
LogStrategy 最终决定FormatStrategy输出日志的目标(如:控制台
LogcatLogStrategy
、磁盘DiskLogStrategy
)
更详细的分析请移步:Android日志系统第三方库------Logger 源码分析
知识点
-
临时tag的实现方法
很简单,
Logger.t("临时tag").d(xxx);
设置临时tag。使用一次就删除。最终也是委托给Printer来实现。为了性能,
LoggerPrinter
和Timber
一样,也使用ThreadLocal
以空间换时间。 -
多线程支持方面,只有
LoggerPrinter
的synchronized void log()
加了锁。个人认为,应该把
LoggerPrinter
的addAdapter(LogAdapter adapter)
和clearLogAdapters()
都加上锁。因为log()方法加锁,所以一定要保证此方法的执行效率。 不然,如果一个线程写日志太耗时,会影响其它线程的执行。
-
接上一条,
DiskLogStrategy
在写文件时,在独立的HandlerThread线程中执行,可以保证LoggerPrinter
的void log()
方法的执行时间。
移植到鸿蒙
通过上面的分析,我们可以知道,移植到鸿蒙需要的工作有:
-
实现
HarmonyLogAdapter
提供 控制台输出 的能力,其中PrettyFormatStrategy
基本可以复用,只要修改LogcatLogStrategy
的实现,用HiLog
替换android.util.Log
相关的操作。 -
修改
DiskLogAdapter
提供 输出日志到文件 的能力。其中CsvFormatStrategy
基本可以复用,只要修改日志文件路径的设置以及Handler
相关的类。修改为:
同理
DiskLogStrategy
里的Handler
也要改为EventHandler
。
思考
上图是最终的效果。从代码中可以看到HiLogLabel是固定的,所以domain
和tag
都是固定的。而为了实现自定义tag的目的,把自定义tag输出到了message里,所以我们可以看到两个"PRETTY_LOGGER",视觉上不太完美。
优化的方法可以参考 Timber_ohos的实现
好文,谢谢分享!!