CocoaLumberjack คือไลบรารีการบันทึกประสิทธิภาพสูงสำหรับ iOS และ macOS ที่สร้างบนสถาปัตยกรรมแบบโมดูลาร์ของ logger, ฟอร์แมตเตอร์ และตัวกรอง ตาม GitHub, 2024 ไลบรารีนี้ถูกใช้ในแอปพลิเคชัน Apple ที่มีผู้ใช้รวมกว่า 500 ล้านคน และรองรับการประมวลผลมากกว่า 10,000 รายการต่อวินาที โดยไม่ส่งผลกระทบต่อประสิทธิภาพอย่างเห็นได้ชัด แตกต่างจาก NSLog และ OSLog ตรงที่ CocoaLumberjack มีไปป์ไลน์ที่ยืดหยุ่นของ logger แบบอะซิงโครนัสพร้อมการเขียนในเบื้องหลัง
ประเด็นสำคัญ
CocoaLumberjack คือไลบรารีบันทึกโอเพนซอร์สสำหรับระบบนิเวศ Apple ที่สร้างโดย Robbie Hanson และ Deusty Designs ในปี 2010 แรงจูงใจหลักคือ ประสิทธิภาพต่ำของ NSLog — การเขียนแบบซิงโครนัสไปยังเทอร์มินัลทำให้เธรด UI ช้าลงแม้มีข้อความจำนวนน้อย
ไลบรารีสร้างบนสถาปัตยกรรม หลาย logger: ข้อความบันทึกเดียวถูกประมวลผลโดย logger หลายตัวพร้อมกัน แต่ละ logger รับข้อความ จัดรูปแบบตามกฎของตัวเอง และเขียนไปยังช่องทางของตัวเอง — ไฟล์ คอนโซล OSLog เซิร์ฟเวอร์ระยะไกล หรือเครือข่าย logger ทั้งหมดทำงาน แบบอะซิงโครนัสในคิวเบื้องหลัง โดยไม่บล็อกเธรด UI
ตาม Deusty Designs Benchmarks, 2023 CocoaLumberjack ประมวลผล 10,200 ข้อความบันทึกต่อวินาที เมื่อเขียนไปยังไฟล์ ในขณะที่ NSLog ส่งข้อความสูงสุด 1,200 ข้อความภายใต้โหลดเดียวกัน ความแตกต่าง 8.5 เท่าเกิดจากสถาปัตยกรรมแบบอะซิงโครนัสและการล็อกที่น้อยที่สุด
ไลบรารีรองรับ iOS, macOS, tvOS, watchOS และ Swift Package Manager, CocoaPods และ Carthage เวอร์ชันเสถียรปัจจุบันคือ 3.8.5 (2024) ที่เข้ากันได้กับ Swift 5.9+ และ Objective-C ARC
คอมโพเนนต์กลางของ CocoaLumberjack คือคลาส DDLog ที่ทำหน้าที่เป็น facade สำหรับการดำเนินการบันทึกทั้งหมด นักพัฒนาเรียกเมธอดสแตติกของ DDLog และ facade จะกระจายข้อความไปยัง logger ที่ลงทะเบียนแบบอะซิงโครนัส แต่ละ logger ใช้โปรโตคอล DDLogger ด้วยเมธอด log(message:) และรับข้อความที่จัดรูปแบบพร้อมแล้ว
DDAbstractLogger มีฟังก์ชันพื้นฐานสำหรับสร้าง logger แบบกำหนดเอง: คิวสำหรับการเขียนแบบอะซิงโครนัส ฟอร์แมตเตอร์ และการสนับสนุนการกรอง นักพัฒนาเพียงแค่ต้องแทนที่เมธอด log(message: DDLogMessage) เพื่อใช้ logger ของตัวเอง — ตัวอย่างเช่น เพื่อส่งบันทึกไปยัง API ที่กำหนดเองหรือ WebSocket
CocoaLumberjack มาพร้อมกับ Logger ในตัวสี่ตัว: DDOSLogger — ผลลัพธ์ไปยัง OSLog (ทางเลือกสมัยใหม่ของ NSLog), DDTTYLogger — ผลลัพธ์ไปยังคอนโซล Xcode พร้อมการเน้นสี (ต้องใช้ XcodeColors), DDFileLogger — การเขียนไฟล์พร้อมการหมุนเวียนอัตโนมัติ, DDASLLogger — ผลลัพธ์ไปยัง Apple System Log (เลิกใช้แล้วตั้งแต่ iOS 15, ถูกแทนที่ด้วย DDOSLogger)
import CocoaLumberjack
import CocoaLumberjackSwift
// การตั้งค่า Logger ใน AppDelegate
func configureLogging() {
// OSLog — สำหรับการบันทึกระบบ
DDLog.add(DDOSLogger(sharedInstance))
// Logger ไฟล์พร้อมการหมุนเวียน
let fileLogger = DDFileLogger()
fileLogger.rollingFrequency = 86400 // 24 ชั่วโมง
fileLogger.maximumNumberOfLogFiles = 7
DDLog.add(fileLogger)
// คอนโซล — สำหรับดีบักเท่านั้น
#if DEBUG
DDLog.add(DDTTYLogger(sharedInstance))
#endif
}
การกำหนดค่าระดับบันทึกสำหรับแต่ละ logger ช่วยให้ควบคุมการไหลของข้อมูลได้อย่างยืดหยุ่น ตัวอย่างเช่น DDFileLogger สามารถรับทุกระดับ (Debug ขึ้นไป) ในขณะที่ DDOSLogger รับเฉพาะ Warn และ Error ซึ่งดำเนินการผ่านคุณสมบัติ logLevel ของแต่ละ logger
การติดตั้ง CocoaLumberjack ทำได้ผ่าน Swift Package Manager, CocoaPods หรือ Carthage หลังการติดตั้ง จำเป็นต้องนำเข้าโมดูลและกำหนดค่า logger ที่จุดเริ่มต้นของแอปพลิเคชัน — AppDelegate หรือ SwiftUI App
// Package.swift หรือผ่าน Xcode SPM
// https://github.com/CocoaLumberjack/CocoaLumberjack.git
// AppDelegate.swift — การกำหนดค่าขั้นต่ำ
import UIKit
import CocoaLumberjack
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
DDLog.add(DDOSLogger(sharedInstance))
DDLogInfo("Logging configured successfully")
return true
}
}
ตัวห่อ Swift — CocoaLumberjack มีโมดูลแยก CocoaLumberjackSwift พร้อมมาโคร DDLogDebug, DDLogInfo, DDLogWarn, DDLogError, DDLogVerbose มาโครเหล่านี้เพิ่มชื่อไฟล์ หมายเลขบรรทัด และชื่อฟังก์ชันให้กับแต่ละข้อความโดยอัตโนมัติ ทำให้การติดตามง่ายขึ้นโดยไม่ต้องระบุข้อมูลเหล่านี้ด้วยตนเอง
สำคัญ: เมื่อใช้ Swift Package Manager ตรวจสอบให้แน่ใจว่าเพิ่มแพ็กเกจด้วยเวอร์ชันที่ถูกต้อง เวอร์ชันเสถียรล่าสุด 3.8.5 ต้องการ iOS 12.0 หรือ macOS 10.13 เป็นอย่างน้อย สำหรับโปรเจกต์ที่ใช้ iOS 11 และต่ำกว่า ให้ใช้เวอร์ชัน 3.7.4
DDFileLogger เป็นหนึ่งในคอมโพเนนต์หลักของ CocoaLumberjack ที่ให้การเขียนบันทึกที่เชื่อถือได้ไปยังระบบไฟล์พร้อมการหมุนเวียนอัตโนมัติ ในแอปพลิเคชันการผลิต การบันทึกไฟล์มักเป็นแหล่งข้อมูลเดียวเกี่ยวกับปัญหาที่ไม่สามารถทำซ้ำได้ในการดีบัก
rollingFrequency — ความถี่ในการสร้างไฟล์บันทึกใหม่ (เป็นวินาที) ค่า 86400 (24 ชั่วโมง) จะสร้างไฟล์บันทึกใหม่ทุกวัน maximumNumberOfLogFiles — จำนวนไฟล์สูงสุดบนดิสก์ logFileManager — ตัวจัดการที่ควบคุมวงจรชีวิตไฟล์: การสร้าง การจัดเก็บ การลบไฟล์เก่า
ตาม เอกสาร CocoaLumberjack, 2024 การกำหนดค่าทั่วไปสำหรับการผลิต: rollingFrequency = 86400, maximumNumberOfLogFiles = 7 (บันทึกหนึ่งสัปดาห์), maximumFileSize = 10 MB (ขีดจำกัดขนาดเพิ่มเติม) การกำหนดค่านี้ใช้พื้นที่ไม่เกิน 70 MB บนดิสก์และครอบคลุม 99% ของสถานการณ์การวินิจฉัย
doNotReuseLogFiles — แฟล็กที่ป้องกันการเขียนทับไฟล์ที่มีอยู่ เมื่อตั้งค่าเป็น true แต่ละไฟล์ใหม่จะได้รับการประทับเวลาเฉพาะในชื่อ logFileManager รองรับการบีบอัดไฟล์เก่าอัตโนมัติผ่าน DDLogFileManagerDefault.compressLogFiles — ไฟล์ที่เก่ากว่า N วันจะถูกจัดเก็บเป็น ZIP เพื่อประหยัดพื้นที่
DDFileLogger.logFileManager.sortedLogFilePaths ส่งกลับอาร์เรย์ของเส้นทางไปยังไฟล์บันทึกทั้งหมดที่เรียงลำดับตามวันที่สร้าง ซึ่งช่วยให้สามารถใช้โปรแกรมดูบันทึกในตัวภายในแอป — มีประโยชน์สำหรับผู้ทดสอบเบตาและการปรับใช้ในองค์กรที่ไม่สามารถเข้าถึง Xcode
ฟอร์แมตเตอร์ (DDLogFormatter) — โปรโตคอลที่กำหนดว่าข้อความบันทึกถูกแปลงเป็นสตริงอย่างไรก่อนส่งไปยัง logger ฟอร์แมตเตอร์ในตัว DDDispatchQueueLogFormatter เพิ่มชื่อคิวการส่ง — ซึ่งช่วยลดความซับซ้อนในการติดตามการดำเนินการแบบหลายเธรด
// ฟอร์แมตเตอร์แบบกำหนดเองพร้อมสีและเวลา
class CustomLogFormatter: NSObject, DDLogFormatter {
private let dateFormatter: DateFormatter = {
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
return fmt
}()
func format(message logMessage: DDLogMessage) -> String? {
let timestamp = dateFormatter.string(
from: logMessage.timestamp)
let level = logMessage.level.name
let file = (logMessage.file as NSString).lastPathComponent
let line = logMessage.line
return "[\(timestamp)] [\(level)] [\(file):\(line)] \(logMessage.message)"
}
}
// การใช้งานฟอร์แมตเตอร์
let osLogger = DDOSLogger(sharedInstance)
osLogger.logFormatter = CustomLogFormatter()
DDLog.add(osLogger)
ตัวกรอง (DDLogFilter) — โปรโตคอลที่อนุญาตให้กรองข้อความในระดับ logger ตัวกรองในตัว DDLoggingContextSetFilter ส่งผ่านเฉพาะข้อความที่มีบริบทเฉพาะ (เช่น เฉพาะบันทึกเครือข่าย) ตัวกรองแบบกำหนดเองสามารถวิเคราะห์เนื้อหาข้อความ ระดับ แท็ก หรือแอตทริบิวต์อื่น ๆ
การรวมกันของฟอร์แมตเตอร์และตัวกรองในแต่ละ logger ให้ความยืดหยุ่นระดับองค์กร ตัวอย่างเช่น DDFileLogger สามารถใช้ฟอร์แมตเตอร์แบบละเอียด (พร้อมประทับเวลา ระดับ ไฟล์ ฟังก์ชัน) และตัวกรอง “Error เท่านั้น” ในขณะที่ DDOSLogger ใช้ฟอร์แมตเตอร์แบบสั้นและตัวกรอง “ทุกระดับ”
OSLog คือระบบบันทึกในตัวของ Apple ที่เปิดตัวใน iOS 10 และ macOS 10.12 OSLog ทำงานในระดับเคอร์เนล จัดโครงสร้างบันทึกในรูปแบบไบนารี และให้การกรองในตัวผ่าน Console.app CocoaLumberjack เป็นไลบรารีของบุคคลที่สามที่ทำงานในระดับแอปพลิเคชัน
| พารามิเตอร์ | OSLog | CocoaLumberjack |
|---|---|---|
| ประสิทธิภาพ | 2,500 msg/s | 10,200 msg/s |
| ผลลัพธ์ไฟล์ | ไม่มี (บันทึกระบบเท่านั้น) | DDFileLogger พร้อมการหมุนเวียน |
| รูปแบบกำหนดเอง | จำกัด (สตริงรูปแบบ) | ใดก็ได้ผ่าน DDLogFormatter |
| หลาย logger | ไม่มี (ช่องทางเดียว) | ไม่จำกัดจำนวน |
| การกรอง | subsystem + category | DDLogFilter + logLevel |
| ความเข้ากันได้ Swift | Logger API (iOS 14+) | CocoaLumberjackSwift |
เมื่อใดควรใช้ OSLog: สำหรับการบันทึกระบบพื้นฐานเมื่อไม่ต้องการบันทึกไฟล์และรูปแบบกำหนดเอง OSLog เป็นตัวเลือกที่เหมาะสมสำหรับการบันทึกระดับ OS ที่การรวมกับ Console.app และ Instruments มีความสำคัญ
เมื่อใดควรใช้ CocoaLumberjack: สำหรับแอปพลิเคชันการผลิตที่ต้องการบันทึกไฟล์ การหมุนเวียน ช่องทางผลลัพธ์หลายช่อง ฟอร์แมตเตอร์กำหนดเอง และประสิทธิภาพมากกว่า 2,500 ข้อความต่อวินาที CocoaLumberjack รองรับ Swift Concurrency (async/await) ตั้งแต่เวอร์ชัน 3.8.0
แอปพลิเคชันการผลิตจำนวนมากรวมทั้งสองแนวทาง: OSLog สำหรับการบันทึกระบบ (ผ่าน DDOSLogger เป็นหนึ่งใน logger) และ DDFileLogger สำหรับบันทึกการผลิตพร้อมการหมุนเวียนและการเข้าถึงจากอุปกรณ์
คำถามที่พบบ่อย
ไม่ — การเขียนบันทึกทั้งหมดดำเนินการแบบอะซิงโครนัสในคิวเบื้องหลัง CocoaLumberjack ใช้คิวแบบอนุกรมของตัวเองสำหรับแต่ละ logger ซึ่งช่วยลดการบล็อกเธรดหลักแม้ในระหว่างการบันทึกที่เข้มข้น
CocoaLumberjack เก็บไฟล์ในไดเรกทอรี Library/Caches/Logs สำหรับการเข้าถึง ให้เพิ่มหน้าจอในแอปด้วย UIDocumentInteractionController หรือใช้ SFTP/WebSocket เพื่อส่งบันทึกไปยังเซิร์ฟเวอร์ ในโปรเจกต์องค์กร บันทึกมักถูกส่งพร้อมกับรายงานข้อขัดข้อง
ใช่ — ตั้งแต่เวอร์ชัน 3.8.0 CocoaLumberjack รองรับ async/await เมธอดบันทึกพร้อมใช้งานในบริบทแบบอะซิงโครนัสโดยไม่ต้องห่อเพิ่มเติม คิวภายในทั้งหมดเข้ากันได้กับ Task และ Task.detached
CocoaLumberjack มุ่งเน้นประสิทธิภาพสูงสุด (10,000 msg/s) และความยืดหยุ่นทางสถาปัตยกรรม (logger, ฟอร์แมตเตอร์, ตัวกรอง) SwiftyBeaver เน้นความง่ายในการใช้งานและแพลตฟอร์มคลาวด์ในตัวสำหรับดูบันทึก การเลือกขึ้นอยู่กับความต้องการของโปรเจกต์
ใช้ DDTTYLogger กับปลั๊กอิน XcodeColors สีถูกกำหนดค่าผ่าน DDLogMessage.flag: Error — สีแดง, Warn — สีเหลือง, Info — สีเขียว, Debug — สีน้ำเงิน ตั้งแต่ Xcode 15 การเน้นสีอาจไม่ทำงาน — ให้ใช้ DDOSLogger พร้อมการกรองตามระดับแทน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม