Skip to content

自定义日志

Rakuyo edited this page Jan 23, 2024 · 9 revisions

RaLog 基于面向协议开发,通过遵循协议,修改默认实现,您可以很方便的自定义日志打印内容,或为您现在有的日志框架提供存储与过滤功能。

目录

自定义

数据模型

自定义符合 RaLog 要求的数据模型很简单,只需声明您自己的数据类型,并使其遵循 LogModelProtocol 协议即可。

除非 LogModelProtocol 协议中的数据不能满足您的需求,否则我们建议您直接使用框架中提供的 Log 类型作为数据源模型。

打印日志

Printable 协议负责格式化日志数据,并将日志输出到控制台。

您需要声明一个自定义类型,并使其遵循 Printable 协议协议,例如:

enum Logger: Printable {}

格式化日志内容

Printable 协议的 format(_:) 方法负责格式化日志数据,并返回格式化好的字符串。

您可以在 Logger 中实现该方法,覆盖掉默认实现:

enum Logger: Printable {

   @inline(__always)
   static func format(_ log: LogModelProtocol) -> String {
       
       // Custom print style
       return """
       
       [\(log.module)][\(log.file)_\(log.function):\(log.line)] \(log.formatTime) <\(log.flag)>: \(log.safeLog)
       """
   }
}

现在当您调用 Logger.debug("This is a log") 时,控制台将输出:

[RaLog][ViewModel.swift_dataSource:47] 10:37:09:064 <👾 Debug>: This is a log

执行打印

Printable 协议的 print(_:) 方法负责调用 Swift.print(_:),将日志输出到控制台。同时还调用了过滤与存储方法。

该方法的默认实现仅在 DEBUG 模式下执行打印与过滤操作,而存储操作则不受此限制。

如果您想更改默认逻辑,则可手动实现该方法。

例如下面的实现,移除了 DEBUG 限制,但是同时没有调用存储与过滤功能的相关方法,这意味着即便 Logger 遵循了 StorableFilterable 协议,依然无法使用存储与过滤功能。

对于应当如何在 print(_:) 方法中调用存储与过滤功能,请参考默认实现:过滤存储

enum Logger: Printable {
    
    @inline(__always) @discardableResult
    static func print<T: LogModelProtocol>(_ log: T) -> T {
        
        log.logedStr = self.format(log)
        
        Swift.print(log.logedStr)
        
        return log
    }
}

日志分类

RaLog 没有采用一般日志系统所使用的 分级 概念,而是使用了 分类 的概念。其实际上是 String 类型的包装:定义

添加您自己的日志分类非常简单,下面的代码演示了如何添加新的日志分类:

extension Log.Flag {
    
    static let curry: Log.Flag = "⭐️ Curry"
    static let note : Log.Flag = "💥 Note"
}

使用新的日志分类与使用其他日志分类无异:

Logger.p("New log flag")(.curry)

或参考内建工具进行封装:

public extension Printable {

    @inline(__always) @discardableResult
    static func note(
        _ kLog: Any?, module: String? = nil, file: String = #file, function: String = #function, line: Int = #line
    ) -> Log {
        return p(kLog, module: module, file: file, function: function, line: line)(.note)
    }
}

存储

Storable 协议负责存储日志。令 Logger 遵循该协议后,实现对应的方法即可替换默认实现。

在默认实现中,RaLog 会将日志模型序列化为 JSON 格式,再存储到 Storable.filePath 对应的文件中。

而读取方法则会读取 JSON 后,再解析为 Model 对象。

您可以手动实现 store(_:) 方法与 readLogFromDisk(logDate:) 方法,以替换掉默认实现。

过滤

Filterable 协议负责过滤日志。令 Logger 遵循该协议后,实现对应的方法即可替换默认实现。

您可以在 Logger 中手动实现 filteredFlags 属性,作为 “被过滤的日志分类的初始值”。

例如您在View基类的 deinit 方法中添加了 Logger.deinit(self) 的日志,但是在一般情况下,您不希望该日志出现在控制台,您只希望在特定时刻,在其他工具中主动的去查看该日志,那么您可以这么做:

enum Logger: Printable, Filterable {

    var filteredFlags: Set<Log.Flag> = [.deinit]
}

接入现有框架

如果您的项目中已经使用了其他日志框架,但是还想接入 RaLog,那么您只需要遵循以下几步:

  1. 令现在的日志模型遵循 LogModelProtocol 协议,或新建一个日志模型,或使用 RaLog.Log 模型。
  2. 令现在的日志工具类遵循 Printable 协议,并实现 print(_:) 方法,在该方法内调用您现有的打印日志的方法。
  3. 如若需要,再令其遵循 StorableFilterable 协议。
  4. 替换所有调用现有打印日志的方法的代码。