简要
OTLogger是一个Android日志库,官方Log 高替版。允许同时把日志 输出到Logcat 和 保存到磁盘。因其内部实现采用策略的设计模式,所以使用者可以根据自己的需求轻松定制该库的每个模块,包括日志输出格式、日志保存方式、捕获异常日志等。
简单使用
kotlin
//使用 QTlogger
LogUtils.v(TAG, "V级别 日志")
LogUtils.d(TAG, "D级别 日志")
LogUtils.i(TAG, "I级别 日志")
LogUtils.w(TAG, "W级别 日志")
LogUtils.e(TAG, "E级别 日志")
就是这样简单,如同 Log 一样直接使用即可。默认会把日志打印到控制台,并且把日志输出到 Android/package/file/log
文件夹下,其输出的日志格式与Log
的格式一致。
OTLogger 的日志格式
OTLogger支持三种默认的日志格式:
LogcatDefaultFormatStrategy
: 默认打印到logcat的日志格式,其格式和Log的输出格式保持一致。 2.LogTxtDefaultFormatStrategy
: 默认打印到磁盘的日志格式,其格式和Log的输出格式保持一致。 3.PrettyFromatStrategy
: 打印到Logcat且比较漂亮的日志格式: 因为该日志格式比较占据空间,所以不建议输出到存储文件中,也就没有实现打印到磁盘的日志格式。
设置日志格式的方式
kotlin
val logger = Logger.Builder()
.setLogcatPrinter(
LogcatCustomPrinter(
true,
LogLevel.V,
PrettyFormatStrategy() //设置打印到Logcat使用PrettyFromatStrategy日志格式
)
)
.build()
LogUtils.setLogger(logger)
定制属于你的日志
以上是OTLogger最简单的使用方式,但是OTLogger能提供的并不仅仅局限于此,你可以基于OTLogger定制一个想要的日志库。
既然要定制,我们先看看OTLogger的实现机制:
上图可以看到,LogUtils下调用的就是Logger,所以我们定义属于自己的日志无非就是定义一自己的Logger。Logger下分为三层:
Printer 层 :打印机层
负责把日志打印到指定的位置,无论是把日志输出到Logcat还是磁盘,都是通过打印机(Printer)进行输出。目前定义有两种类型的打印机:
1. BaseLogcatPrinter: Logcat打印机
负责打印日志到Logcat,是一个抽象类。当我们需要定制自己的Logcat Printer 的时候,可以继承并重写BaseLogcatPrinter
内部的方法即可。你也可以继承我们已经实现的 Logcat Printer :
LogcatDefaultPrinter
:默认 的Logcat Printer,采用了LogcatDefaultFormatStrategy
日志格式,最低日志输出级别是:V
LogcatCustomPrinter
: 可自定义的 Logcat Printer。
kotlin
/**
* 自定义 Loacat 打印机
* @property printable 是否打印日志到 logcat
* @property minLevel 最小日志输出级别
* @property formatStrategy 日志格式策略,选择你想要的日志格式策略
*/
open class LogcatCustomPrinter(val printable:Boolean
, val minLevel: LogLevel
, val formatStrategy:BaseFormatStrategy
):BaseLogcatPrinter()
2.BaseLogTxtPrinter: 磁盘打印机
负责打印日志到磁盘文件中,是一个抽象类。当我们需要定制自己的 磁盘 Printer 的时候,可以继承并重写BaseLogTxtPrinter
内部的方法即可。你也可以继承我们已经实现的 LogTxt Printer :
LogTxtDefaultPrinter
:默认的 的LogTxt Printer。内部采用了LogTxtDefaultFormatStrategy
日志格式,最低日志输出级别是:V
。LogTxtCustomPrinter
:可自定义的 LogTxt Printer。
kotlin
/**
* 自定义日志文件打印机
* @property printable 是否写入到文件
* @property minLevel 最低输出日志
* @property formatStrategy 日志格式策略
* @property diskStrategy 文件管理策略
*/
open class LogTxtCustomPrinter(val printable:Boolean
, val minLevel:LogLevel
, val formatStrategy: BaseFormatStrategy
, val diskStrategy:BaseLogDiskStrategy
):BaseLogTxtPrinter()
Format 层:日志格式层
该层定义了日志输出的格式,通过继承BaseFormatStrategy
实现,每个Printer都包含一个FormatStrategy,所以每个Printer 都可以拥有自己的日志格式。目前OTLogger 已经包含了三种日志格式:
-
LogcatDefaultFormatStrategy
:(输出到Logcat专属) 默认输出到Logcat的日志格式,在BaseLogcatPrinter
中采用该日志格式,输出的日志和Log打印到Logcat是一致的。 -
PrettyFormatStrategy
: (输出到Logcat专属) 漂亮的日志格式。 -
LogTxtDefaultFormatStrategy
:(输出到磁盘专属) ,默认输出到磁盘的日志格式。
注意: 上面特意标注了该日志格式是'Logcat'还是'磁盘'专属是有意义的。因为:
- 输出到Logcat的日志本质上还是调用
Log.println(int priority, String tag, String msg)
函数进行打印,所以我们无法定制输出的时间、PID 等信息;只能定制其中的 msg 信息,所以专属Logcat的BaseFormatStrategy.format()
返回的String对应的msg参数。- 相对的,专属磁盘的
BaseFormatStrategy.format()
返回的String对应打印到磁盘的整条日志信息。
Disk层:磁盘管理层
该层管理了所有的日志文件,只有 LogTxt Printer才会使用到,主要解决的问题:
每一行日志打印打印到哪个文件中?
何时分配一个新的日志文件?
何时回收旧的日志文件?
该层通过通过继承抽象类BaseLogDiskStrategy
实现。目前已经实现的DiskStrategy:
TimeLogDiskStrategyImpl
:按时间管理日志文件;默认按照小时创建日志文件,默认日志文件保存七天,默认日志文件名:log_年_月_日_时间段.log
,例:
c
//2023年2月12日15时到16时
otLog_2023_02_12_15_16.log
-
FileLogDiskStrategyImpl
:日志文件管理策略,按存储空间管理日志文件。- 默认每个日志文件5MB,参考
getLogFileMaxSizeOfMB
- 默认日志文件夹最大可容纳 100M日志,超过
getLogDirMaxStoreOfMB
会按照时间顺序删除旧的日志,直到低于预定值 - 默认文件名 otLog_年_月_日_时_分_秒.log , 例 : otLog_2023_02_12_16_28_56.log
- 默认每个日志文件5MB,参考
-
FileAndTimeDiskStrategyImpl
: 文件+时间管理策略,同时具备FileLogDiskStrategyImpl
和TimeLogDiskStrategyImpl
的特性。- 默认日志文件夹最大可容纳 100M日志,超过
getLogDirMaxStoreOfMB
会按照时间顺序删除旧的日志,直到低于预定值 - 默认文件名 默认文件名 log_年_月_日_时间段_创建时间戳.log ,例:
bashotLog_2023_02_12_16_17_1233644846.log
- 默认日志文件夹最大可容纳 100M日志,超过
注意:
以上所有的磁盘管理都是默认存储日志的文件夹都是
storage/emulated/0/Android/data/packageName/files/log
,我们可以通过重写getLogDir()
方法指定我们的日志文件夹。
理解了上面的OTLogger后,我们就知道如何去定义属于我们自己的日志。下面我举几个案例:
- 实现和默认OTLogger一样的效果:
kotlin
val logger = Logger.Builder()
//设置Logcat Printer
.setLogcatPrinter(LogcatDefaultPrinter())
//设置LogTxt Printer
.setLogTxtPrinter(LogTxtDefaultPrinter())
.build()
LogUtils.setLogger(logger)
- 设置Logcat使用
PrettyFormatStrategy
格式,并且Logcat和logTxt中Debug级别以下的日志不输出:
kotlin
val logger = Logger.Builder()
//设置Logcat Printer, 最低输出日志级别:Debug, 使用PrettyFormatStrategy 日志格式
.setLogcatPrinter(LogcatCustomPrinter(true,LogLevel.D,PrettyFormatStrategy()))
//设置LogTxt Printer, 最低输出日志级别:Debug, 使用LogTxtDefaultFormatStrategy日志格式(默认),TimeLogDiskStrategyImpl 磁盘管理格式(默认)
.setLogTxtPrinter(LogTxtCustomPrinter(true,LogLevel.D,LogTxtDefaultFormatStrategy(),TimeLogDiskStrategyImpl()))
.build()
LogUtils.setLogger(logger)
- 日志文件管理策略使用
FileAndTimeDiskStrategyImpl
- 指定日志文件夹是
storage/emulated/0/Android/data/packageName/files/myAppLog
; - 指定每个日志文件最大存储15M;
- 指定整个日志文件夹最大存储500M日志文件;
- 指定系统至少要剩下600M容量时候才能继续写入日志(避免日志把磁盘写满);
kotlin
val diskStrategy = object :FileAndTimeDiskStrategyImpl(){
override fun getLogDir(): String {
//指定日志文件夹是`storage/emulated/0/Android/data/packageName/files/myAppLog`;
return app.getExternalFilesDir("")?.absolutePath+ File.separator+"myAppLog"
}
override fun getLogFileMaxSizeOfMB(): Long {
//指定每个日志文件最大存储15M;
return 15
}
override fun getLogDirMaxStoreOfMB(): Long {
//指定整个日志文件夹最大存储500M日志文件;
return 500
}
override fun getMinFreeStoreOfMB(): Long {
//指定系统至少要剩下600M容量时候才能继续写入日志(避免日志把磁盘写满);
return 600
}
}
val logger = Logger.Builder()
//设置Logcat Printer, 最低输出日志级别:Debug, 使用PrettyFormatStrategy 日志格式
.setLogcatPrinter(LogcatCustomPrinter(true,LogLevel.D,PrettyFormatStrategy()))
//设置LogTxt Printer, 最低输出日志级别:Debug, 使用LogTxtDefaultFormatStrategy日志格式(默认),TimeLogDiskStrategyImpl 磁盘管理格式(默认)
.setLogTxtPrinter(LogTxtCustomPrinter(true,LogLevel.D,LogTxtDefaultFormatStrategy(),diskStrategy))
.build()
LogUtils.setLogger(logger)