先日、PuppyというSwiftログライブラリをつくりました。本ライブラリは、apple/swift-logのREADMEにもapple/swift-logのバックエンドコンパチログライブラリの1つとしても記載されています。また、単体の(例えばiOS向けの)ログライブラリとしても使うことができるようになっており、LinuxとDarwin(macOS/iOS/tvOS/watchOS)のいずれの環境でも動作します。サーバーサイドSwiftに興味のある方はもちろんのことiOSアプリ等を開発をする方にも一度使ってみてもらえればと思います。
https://github.com/sushichop/Puppy
※ STARをもらえると励みになります🙂
なぜつくったのか?
私はObjective-C全盛時代によく使われていたログライブラリCocoaLumberjackのメンテナの1人として今現在もメンテナ活動を続けています。少なくとも昔はよくできたライブラリだとは思いますが、Swift環境では使いにくい、Linux環境では使えない等の問題があります。
私が必要としていたのは、1つのライブラリでLinux、Dwarinのいずれの環境でも十分に使えること、及びログローテーションをサポートしていることでした。特に必要としていたのはLinux環境におけるファイルログローテーション機能です。
既存のOSSのSwiftログライブラリでは私の需要を満たせなかったので、自ら作ることにしました。
ライブラリ名 | Linuxサポート | syslog(Linux)サポート | ログローテーション機能 | apple/swift-logサポート |
---|---|---|---|---|
SwiftyBeaver | ✅ | N/A | N/A | N/A |
XCGLogger | N/A | N/A | ✅ | N/A |
Puppy | ✅ | ✅ | ✅ | ✅ |
動作環境
- Swift 5.0以上(Swift 5.3以上推奨)
- CocoaPods、Carthage、Swift Package Manager
使い方
ロギング先としてコンソール、ファイル、syslog(Linux)等をサポートしています。カスタムログフォーマットにも対応しています。詳しくはsushichop/PuppyのREADMEを参照してもらえればと思いますが、以下に使い方の例を2つ簡単に書いておきます。
使い方その1(ファイルログローテーション)
下記はファイルへロギングしつつ、10MBのログファイルを5つまでログローテーションする例です。FileRotationLogger
の第1引数にはIDとなる逆FQDN形式の文字列を指定してください。第2引数にはファイル名を指定します。ログローテーション完了通知についてはdelegate
で実現しています。
import Puppy
class ViewController: UIViewController {
let delegate = SampleFileRotationDelegate()
override func viewDidLoad() {
super.viewDidLoad()
let fileRotation = try! FileRotationLogger("com.example.yourapp.filerotation", fileURL: "./rotation/foo.log")
fileRotation.maxFileSize = 10 * 1024 * 1024
fileRotation.maxArchivedFilesCount = 5
fileRotation.delegate = delegate
let log = Puppy()
log.add(fileRotation)
log.info("INFO message")
log.warning("WARNING message")
}
}
class SampleFileRotationDelegate: FileRotationLoggerDeletate {
func fileRotationLogger(_ fileRotationLogger: FileRotationLogger,
didArchiveFileURL: URL, toFileURL: URL) {
print("didArchiveFileURL: \(didArchiveFileURL), toFileURL: \(toFileURL)")
}
func fileRotationLogger(_ fileRotationLogger: FileRotationLogger,
didRemoveArchivedFileURL: URL) {
print("didRemoveArchivedFileURL: \(didRemoveArchivedFileURL)")
}
}
使い方その2(apple/swift-logバックエンド)
apple/swift-logバックエンドとして使う場合は、Carthageは利用できません。これはapple/swift-logがCarthageをサポートしていないためです。CocoaPodsまたはSwift Package Managerを使ってインテグレーションしてください。
下記はコンソールとsyslogへロギングする例です。Puppy
に加えてLogging
もインポートする必要がある点に注意ください。
import Puppy
import Logging
let console = ConsoleLogger("com.example.yourapp.console")
let syslog = SystemLogger("com.example.yourapp.syslog")
let puppy = Puppy.default
puppy.add(console)
puppy.add(syslog)
LoggingSystem.bootstrap {
var handler = PuppyLogHandler(label: $0, puppy: puppy)
// Set the logging level.
handler.logLevel = .trace
return handler
}
log.trace("TRACE message") // Will be logged.
log.debug("DEBUG message") // Will be logged.
その他(補足)
本ライブラリでは、あえて実装していない機能等もあります。その1つが__dispatch_queue_get_label(nil)
関数によるDispatchキューラベル取得機能です。これは、Linux環境で使えないこと、及びここにもあるように本関数を呼び出すことにより、潜在的にクラッシュする可能性があるためです。
どうしても使いたい場合は、本ライブラリではLogFormattable
プロトコルによるカスタムログフォーマットに対応していますので、ライブラリ利用者は必要に応じて本プロトコル実装の中で、上記関数を呼び出すことにより対応できます。
最後に
今回つくったSwiftログライブラリPuppyについては、Linux/Darwinの両環境で動作することを重視しており、今後も適宜改版していく予定です。サーバサイドSwift盛り上がっていくといいですね🙂