Swift SwiftLog、Extension追加、欲しいログ機能にしてみる
SwiftLogとは
https://github.com/apple/swift-log
Home Pageより
Swift用のロギングAPIパッケージです。バージョン1.0.0.0はSwift 5.0を必要としますが、Swift 5への移行を容易にするためにSwift 4用のバージョン0.x.yシリーズが用意されています。Swift4でSwiftLogを使用したり、サポートしたりする予定がある場合は、ドキュメントの最後にある段落を確認してください。
まず第一に。これは、コードであれ、ドキュメントであれ、アイデアであれ、積極的に貢献を求めているコミュニティ主導のオープンソースプロジェクトの始まりです。SwiftLog自体への貢献とは別に、現時点ではもう一つ大きなギャップがあります。SwiftLogは、エコシステムが使用できる共通のAPIを確立しようとするAPIパッケージです。ロギングを実世界のワークロードで本当に機能させるためには、ログメッセージをファイルに永続化したり、端末上でより良い色で表示したり、SplunkやELKに送信したりするSwiftLog互換のロギングバックエンドが必要です。
SwiftLogが現在提供しているものはAPIドキュメントにあります。
printからの脱却
本来「SwiftLog互換のロギングバックエンドが必要」なのですが、Xcode Outputで使用する範囲であればSwiftLogで問題ない。
そのままでも日時は表示される。
デバッグ使用するにはクラス名、メソッド名、ライン数は欲しい。
metadataで表示させる方法もあるが、表示が「function=関数名」(例)となり、格好良くない。
互換ライブラリ一覧がGitHubページに掲載れています。それを使えば解決するが、開発してみる。
LogHandlerベースで互換ライブラリ開発ではなく、Extensionを使った開発。
LoggerExtension.swift
import Logging extension Logger { static var level = Logger.Level.info init(function: String = #function) { self.init(label: function) self.logLevel = Logger.level } func trace(_ message: String = "" , function: String = #function, line: Int = #line) { self.trace(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)"))) } func debug(_ message: String = "" , function: String = #function, line: Int = #line) { self.debug(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)"))) } func info(_ message: String = "" , function: String = #function, line: Int = #line) { self.info(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)"))) } func notice(_ message: String = "" , function: String = #function, line: Int = #line) { self.notice(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)"))) } func warning(_ message: String = "" , function: String = #function, line: Int = #line) { self.warning(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)"))) } func error(_ message: String = "" , function: String = #function, line: Int = #line) { self.error(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)"))) } func critical(_ message: String = "" , function: String = #function, line: Int = #line) { self.critical(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)"))) } }
使用Example
SwingLogの使い方と変わらない。
initとログ出力(info等)は引数なしを用意した。
import UIKit import Logging class ViewController: UIViewController { let logger = Logger() override func viewDidLoad() { super.viewDidLoad() logger.info() logger.info("start") : :
表示例
2020-09-27T10:30:15+0900 info ViewController : [viewDidLoad():70]