-
Notifications
You must be signed in to change notification settings - Fork 2
高级功能
如果您还没有阅读过构成组件,那么我们建议您先阅读该章节,再阅读本章内容,这将有助于您理解本章内容。
-
如果您打算通过内建的
Log
类型打印、操作日志,那么您无需任何其他额外的代码,即可使用本章节内提到的所有功能。或者稍加配置,即可达成您想要的效果。 -
如果您参考了自定义日志章节,打算通过自定义类型打印、操作日志,那么您可以将下文中所有的
Log
类型替换为您的自定义类型。 -
如果您使用自定义类型,那么我们还要提醒您,使用以下功能时,请确保 “打印与存储/读取”、“打印与过滤” 的是同一类型。即使用存储功能时,遵循
Printable
和Storable
的是同一类型;使用打印功能时,遵循Printable
和Filterable
的是同一类型。
RaLog
通过 Storable
协议,实现了对日志的存储、读取与删除功能。
借助 StorageMode
类型,用户可以指定将日志存储在磁盘、内存或两者全部(OptionSet
)。
在默认条件下,RaLog
采用的是 两者全部 的存储策略。
您可以通过 Log.filePath
属性,更改日志的本地存储路径,或通过 Log.storageMode
属性,更改存储方式。
您无需执行额外的存储方法,即可享受存储功能。相关内容,可参考具体实现
截止 1.2.2 版本,
RaLog
尚不提供灵活的,针对单条日志的存储策略。如果您想单独决定某条日志的存储方式,您只能在该条日志输出前,更改Log.storageMode
属性的值,且该操作将一直生效,知道您再次修改它。
您可通过 Log.logs
属性,读取自应用程序启动后,缓存到内存中的所有日志。
Storable
默认提供的读取磁盘中存储的日志的方法如下所示:
默认实现为该方法添加了
logDate: Date = Date()
的默认参数。
/// 从磁盘中读取与 `logDate` 相对应的日期的日志数据。
///
/// - Note: 默认实现未判断 `storageMode` 属性。也就是说,当 `storageMode` 不包含 `.disk` 时,本方法仍将尝试从磁盘读取日志数据。
//
/// - Parameter logDate: 要读取的日志的日期。
static func readLogFromDisk<T: LogModelProtocol>(logDate: Date) -> [T]?
您可通过 Log.readLogFromDisk()
读取当天的日志数据,或通过 Log.readLogFromDisk(logDate: someDate)
来读取某天的日志数据。
基于该方法,我们还扩展了 Storable
,提供了另外两个读取方法,用来读取某一范围内的日志数据:
/// 读取前 `days` 天的日志数据。
///
/// 当 `days` 为 1 时, 将读取前 1 天的数据,即**昨天**的日志数据。
/// 当 `days` 为 2 时, 将读取前 2 天的数据,即**前天**的日志数据。
/// 以此类推
///
/// - Parameter days: 天数。
/// - Returns: 所读取那天的日志数据。
static func readLogFromDisk<T>(days: Int) -> [T]? where T : RaLog.LogModelProtocol
/// 读取某些时间点,或时间段内的日志数据。
///
/// `days` 可以是时间段(`ClosedRange<Int>`)
/// 例如, 当传入 `0 ... 7` 时, 意味着读取7天之内的数据(包括当天,即一共8天的数据)。
///
/// `days` 也可以是时间点 (`[Int]`)
/// 例如, 当传入 `[1, 3, 5]` 时, 意味着读取前1天、前3天、前5天的日志数据,即共3天的日志数据。
///
/// - Note:
/// 正数表示当前日期之前的时间。
///
/// - Attention:
/// 该方法将对 `days` 变量调用 `reversed()` 方法。请注意参数集合中元素的顺序。
///
/// - Parameters:
/// - days: 时间点或时间段。
/// - strategy: 中断方法执行的策略,详见 `BreakStrategy`。 默认为 `.never`。
/// - Returns: 获得的日志。 当整体为“ nil”时,表示没有日志,而当内部数组为“ nil”时,表示当天没有日志。
static func readLogFromDisk<C, T>(days: C, strategy: BreakStrategy = .never) -> [[T]?]? where C : Collection, T : RaLog.LogModelProtocol, C.Element == Int
Storable 默认提供的删除磁盘中存储的日志的方法如下所示:
默认实现为该方法添加了
logDate: Date = Date()
的默认参数。
/// 从磁盘删除取与 `logDate` 相对应的日期的日志数据。
///
/// - Note: 默认实现未判断 `storageMode` 属性。也就是说,当 `storageMode` 不包含 `.disk` 时,本方法仍将尝试从磁盘读取日志数据。
//
/// - Parameter logDate: 要读取的日志的日期。
/// - Return: 如果删除成功,将返回 `.success(())`,否则将返回错误消息。
static func removeLogFromDisk(logDate: Date) -> Result<Void, Error>
您可通过 Log.removeLogFromDisk()
删除当天全部的日志数据,或通过 Log.removeLogFromDisk(logDate: someDate)
来删除某天全部的日志数据。
日志的过滤功能不会影响存储功能,即被过滤的日志依然可以被正确存储。
RaLog
通过 Filterable
协议,实现了对日志的过滤功能,被过滤的日志将不会在控制台进行输出。
过滤方式有以下两种:
- 按日志分类过滤
- 按文件名过滤
RaLog
支持按日志分类对输出的日志进行过滤。
- 您可以通过
Set<Log.Flag>
类型的Log.filteredFlags
属性,静态的设置初始所要过滤的日志分类。 - 或者通过
Log.addFilter(flag: ...)
或Log.addFilter(flag: ...)
动态的增加/删除所要过滤的日志分类。
RaLog
支持按文件名对输出的日志进行过滤。
- 您可以通过
Set<String>
类型的Log.filteredFiles
属性,静态的设置初始所要过滤的文件。 - 或者通过
Log.fileterCurrentFileLogs(...)
方法,过滤当前文件(默认实现),或某一特定文件的日志输出。
截止 1.2.2 版本,
RaLog
暂时没有提供额外的取消文件过滤的方法。如有需要,您可直接操作Log.filteredFiles
属性。
您无需执行额外的过滤方法,即可享受过滤功能。相关内容,可参考具体实现
在设计上,Printable
协议中负责输出的 print(...)
方法接收一个遵循 LogModelProtocol
协议的泛型模型。然而在使用上,这是非常不方便的。
所以在内建工具文件中,我们对 print(...)
方法进行了封装:
public extension Printable {
@inline(__always) @discardableResult
static func p(
_ kLog: Any?, module: String? = nil, file: String = #file, function: String = #function, line: Int = #line
) -> (Log.Flag) -> Log {
return { print(Log(kLog, file: file, function: function, line: line, flag: $0, module: module)) }
}
}
执行该方法后,并不会立刻打印日志,而是会返回一个 (Log.Flag) -> Log
类型的闭包。调用该闭包并传入日志分类,才会执行打印操作。
像是上文中提到的 Log.debug(...)
方法,即是对该方法的进一步封装。
如此设计 p(...)
方法的好处在于,您可以通过该方法更加灵活的输出日志:
- 假如您在基类中调用
Log.appear(...)
,但又想在某个特殊的控制器中修改该方法的输出内容,并且依然想使用.jump
分类,那么最简单的方法就是执行Log.p(...)(.jump)
。 - 如果您想封装自定义的日志分类,可使用
p(...)
方法,并参考内建工具中提供的方法,封装自己的日志打印方法。