
XCGLOGGER是用於在Swift Projects中使用的原始調試日誌模塊。
Swift不包括C預處理器,因此開發人員無法使用他們在Objective-C中使用的調試日誌#define宏。這意味著我們傳統的生成良好調試日誌的方式不再有效。訴諸普通的舊print電話意味著您會丟失很多有用的信息,或者要求您鍵入更多代碼。
XCGLOGGER允許您將詳細信息登錄到控制台(以及可選的文件或其他自定義目的地),就像使用NSLog()或print()一樣,但是還有其他信息,例如日期,函數名稱,文件名和行號。
從中走:
Simple message
因此:
2014-06-09 06:44:43.600 [Debug] [AppDelegate.swift:40] application(_:didFinishLaunchingWithOptions:): Simple message
執行:
git submodule add https://github.com/DaveWoodCom/XCGLogger.git
在您的存儲庫文件夾中。
將以下行添加到您的Cartfile中。
github "DaveWoodCom/XCGLogger" ~> 7.1.5
然後運行carthage update --no-use-binaries或僅僅是carthage update 。有關迦太基的安裝和使用的詳細信息,請訪問其項目頁面。
在Swift中運行5.0及以上的開發人員需要將$(SRCROOT)/Carthage/Build/iOS/ObjcExceptionBridging.framework添加到其輸入文件中的“複製迦太基框架構建階段”。
將類似於以下行的內容添加到您的Podfile中。您可能需要根據平台,版本/分支等進行調整。
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
use_frameworks!
pod 'XCGLogger', '~> 7.1.5'
單獨指定POD XCGLogger將包括核心框架。我們開始添加亞種,以允許您包括可選組件:
pod 'XCGLogger/UserInfoHelpers', '~> 7.1.5' :包含一些實驗代碼,以幫助使用UserInfo詞典來標記日誌消息。
然後運行pod install 。有關Cocoapods的安裝和使用的詳細信息,請訪問其官方網站。
注意:在Cocoapods 1.4.0之前,不可能使用具有快速版本混合物的多個POD。您可能需要確保為正確的Swift版本配置每個POD(檢查工作空間的POD項目中的目標)。如果您手動調整項目的SWIFT版本,則下次運行pod install時將重置。您可以將post_install掛鉤添加到您的Podfile中,以自動設置正確的Swift版本。這在很大程度上沒有測試,我不確定這是一個很好的解決方案,但似乎有效:
post_install do |installer|
installer.pods_project.targets.each do |target|
if ['SomeTarget-iOS', 'SomeTarget-watchOS'].include? "#{target}"
print "Setting #{target}'s SWIFT_VERSION to 4.2n"
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.2'
end
else
print "Setting #{target}'s SWIFT_VERSION to Undefined (Xcode will automatically resolve)n"
target.build_configurations.each do |config|
config.build_settings.delete('SWIFT_VERSION')
end
end
end
print "Setting the default SWIFT_VERSION to 3.2n"
installer.pods_project.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '3.2'
end
end
當然,您可以對其進行調整以滿足您的需求。
將以下條目添加到包裹的依賴項中:
.Package(url: "https://github.com/DaveWoodCom/XCGLogger.git", majorVersion: 7)
使用:
此快速啟動方法的目的是為了讓您與記錄器一起運行。但是,您應該在下面使用高級用法來充分利用此庫。
將XCGLOGGER項目作為子項目添加到您的項目中,並添加適當的庫作為目標的依賴。在目標的General選項卡下,添加XCGLogger.framework和ObjcExceptionBridging.framework到Embedded Binaries部分。
然後,在每個源文件中:
import XCGLogger在您的AppDelegate(或其他全局文件)中,向默認的XCGlogger實例聲明全局常數。
let log = XCGLogger . default在
application ( _ application : UIApplication , didFinishLaunchingWithOptions launchOptions : [ UIApplicationLaunchOptionsKey : Any ] ? = nil ) // iOS, tvOS或者
applicationDidFinishLaunching ( _ notification : Notification ) // macOS功能,配置您需要的選項:
log . setup ( level : . debug , showThreadName : true , showLevel : true , showFileNames : true , showLineNumbers : true , writeToFile : " path/to/file " , fileLevel : . debug ) writeToFile:可以是String或URL 。如果該文件已經存在,則將在我們使用該文件之前清除。省略參數或將其設置nil以登錄到控制台。您可以選擇使用fileLevel:參數設置文件輸出的不同日誌級別。將其設置為nil或省略以使用與控制台相同的日誌級別。
然後,只要您想記錄某些內容,請使用一種便利方法:
log . verbose ( " A verbose message, usually useful when working on a specific problem " )
log . debug ( " A debug message " )
log . info ( " An info message, probably useful to power users looking in console.app " )
log . notice ( " A notice message " )
log . warning ( " A warning message, may indicate a possible error " )
log . error ( " An error occurred, but it's recoverable, just info about what happened " )
log . severe ( " A severe error occurred, we are likely about to crash now " )
log . alert ( " An alert error occurred, a log destination could be made to email someone " )
log . emergency ( " An emergency error occurred, a log destination could be made to text someone " )不同的方法設置了消息的日誌級別。 XCGLOGGER將僅打印具有更大到或等於其當前日誌級別設置的日誌級別的消息。因此,具有.error級別的記錄器只能輸出以.error , .severe , .alert和.emergency的級別輸出日誌消息。
XCGLOGGER的目標是易於使用,並在上面的2行代碼下快速啟動和快速運行。但是它可以更大的控制和靈活性。
可以將記錄器配置為將日誌消息傳遞到各種目的地。使用上面的基本設置,Logger將將日誌消息輸出到標準Xcode調試控制台,如果提供了路徑,則可以選擇一個文件。您很可能需要將日誌發送到更有趣的地方,例如Apple系統控制台,數據庫,第三方服務器或其他應用程序(例如NSlogger)。這是通過將目的地添加到記錄器來實現的。
這是配置記錄器以輸出到Apple系統日誌和文件的示例。
// Create a logger object with no destinations
let log = XCGLogger ( identifier : " advancedLogger " , includeDefaultDestinations : false )
// Create a destination for the system console log (via NSLog)
let systemDestination = AppleSystemLogDestination ( identifier : " advancedLogger.systemDestination " )
// Optionally set some configuration options
systemDestination . outputLevel = . debug
systemDestination . showLogIdentifier = false
systemDestination . showFunctionName = true
systemDestination . showThreadName = true
systemDestination . showLevel = true
systemDestination . showFileName = true
systemDestination . showLineNumber = true
systemDestination . showDate = true
// Add the destination to the logger
log . add ( destination : systemDestination )
// Create a file log destination
let fileDestination = FileDestination ( writeToFile : " /path/to/file " , identifier : " advancedLogger.fileDestination " )
// Optionally set some configuration options
fileDestination . outputLevel = . debug
fileDestination . showLogIdentifier = false
fileDestination . showFunctionName = true
fileDestination . showThreadName = true
fileDestination . showLevel = true
fileDestination . showFileName = true
fileDestination . showLineNumber = true
fileDestination . showDate = true
// Process this destination in the background
fileDestination . logQueue = XCGLogger . logQueue
// Add the destination to the logger
log . add ( destination : fileDestination )
// Add basic app info, version info etc, to the start of the logs
log . logAppDetails ( )您可以根據您的需求配置每個日誌目標。
另一個常見的用法模式是有多個登錄器,也許是一個用於UI問題,一個用於網絡,另一種用於數據問題。
每個日誌目的地都可以具有自己的日誌級別。為了方便起見,您可以在日誌對象本身上設置日誌級別,並將該級別傳遞給每個目的地。然後設置需要不同的目的地。
注意:只能將目標對象添加到一個logger對像中,將其添加到第二個對象將將其從第一個刪除。
另外,您可以使用封閉來初始化全局變量,以便在一個地方完成所有初始化
let log : XCGLogger = {
let log = XCGLogger ( identifier : " advancedLogger " , includeDefaultDestinations : false )
// Customize as needed
return log
} ( )注意:這會懶惰地創建日誌對象,這意味著直到實際需要之前就不會創建它。這延遲了應用程序信息詳細信息的初始輸出。因此,如果您還沒有在應用程序啟動中登錄某些內容let _ = log則建議在應用程序啟動時強制在應用didFinishLaunching啟動時創建日誌對象。
您可以記錄字符串:
log . debug ( " Hi there! " )或幾乎所有您想要的東西:
log . debug ( true )
log . debug ( CGPoint ( x : 1.1 , y : 2.2 ) )
log . debug ( MyEnum . Option )
log . debug ( ( 4 , 2 ) )
log . debug ( [ " Device " : " iPhone " , " Version " : 7 ] )XCGlogger 4的新手,您現在可以創建過濾器以應用於您的記錄器(或特定目的地)。創建和配置過濾器(下面的示例),然後將它們添加到Logger或目標對像中,將可選的filters屬性設置為包含過濾器的數組。過濾器以數組中存在的順序應用。在處理過程中,詢問每個過濾器是否應將日誌消息排除在日誌之外。如果有任何過濾器不包括日誌消息,則將其排除在外。過濾器無法扭轉排除另一個過濾器的排除。
如果目標的filters屬性nil ,則使用日誌filters屬性。要擁有一個目標日誌所有內容,同時讓所有其他目的地過濾一些東西,請將過濾器添加到日誌對像中,並將一個目標的filters屬性設置為空數組[] 。
注意:與目的地不同,您可以將相同的過濾對象添加到多個登錄器和/或多個目的地。
要將所有日誌消息排除在特定文件中,請創建類似的排除過濾器:
log . filters = [ FileNameFilter ( excludeFrom : [ " AppDelegate.swift " ] , excludePathWhenMatching : true ) ] excludeFrom:取一個Array<String>或Set<String>因此您可以同時指定多個文件。
excludePathWhenMatching:默認為true因此您可以省略它,除非您也想匹配路徑。
要僅適用於文件的特定集合的日誌消息,請使用includeFrom: Initializer創建過濾器。也可以僅切換inverse屬性以將排除過濾器翻轉為包含過濾器。
為了通過標籤過濾日誌消息,您當然必須能夠在日誌消息上設置標籤。現在,每個日誌消息都可以包含附加到其附加的用戶定義的數據,將由過濾器(和/或格式化器等)使用。這是用userInfo: Dictionary<String, Any>對象來處理的。字典鍵應為命名式字符串,以避免與未來添加的碰撞。官方密鑰將從com.cerebralgardens.xcglogger開始。 XCGLogger.Constants.userInfoKeyTags可以訪問標籤鍵。您絕對不想打字,因此請隨時創建一個全局快捷方式: let tags = XCGLogger.Constants.userInfoKeyTags 。現在,您可以輕鬆地標記您的日誌:
let sensitiveTag = " Sensitive "
log . debug ( " A tagged log message " , userInfo : [ tags : sensitiveTag ] )標籤的值可以是Array<String> , Set<String> ,也可以是String ,具體取決於您的需求。過濾時它們都以相同的方式工作。
根據您的工作流程和用法,您可能會創建更快的方法來設置userInfo字典。有關其他可能的快捷方式,請參見下文。
現在,您已經標記了日誌,可以輕鬆過濾:
log . filters = [ TagFilter ( excludeFrom : [ sensitiveTag ] ) ]就像FileNameFilter一樣,您可以使用includeFrom:或inverse切換以僅包含具有指定標籤的日誌消息。
開發人員的過濾就像通過標籤過濾,僅使用XCGLogger.Constants.userInfoKeyDevs的userInfo鍵。實際上,這兩個過濾器都是UserInfoFilter類的子類,您可以使用它們來創建其他過濾器。請參閱下面的XCGLOGGER。
在具有多個開發人員的大型項目中,您可能需要開始標記日誌消息,並指出添加了該消息的開發人員。
雖然非常靈活,但userInfo字典可能會有些麻煩。您可以簡單地使用一些可能使用的方法。我仍在自己測試它們,因此它們還沒有正式屬於圖書館的一部分(我喜歡反饋或其他建議)。
我創建了一些實驗代碼來幫助創建UserInfo詞典。 (如果使用CocoApods,請包括可選的UserInfoHelpers亞種)。檢查iOS演示應用程序以查看使用中的應用。
有兩個符合UserInfoTaggingProtocol協議的結構。 Tag和Dev 。
您可以對適合您項目的每個項目創建一個擴展名。例如:
extension Tag {
static let sensitive = Tag ( " sensitive " )
static let ui = Tag ( " ui " )
static let data = Tag ( " data " )
}
extension Dev {
static let dave = Dev ( " dave " )
static let sabby = Dev ( " sabby " )
}除這些類型外,還有一個超載的操作員|可以用來將它們合併到與UserInfo:日誌記錄呼叫的參數兼容的字典中。
然後,您可以這樣記錄消息:
log . debug ( " A tagged log message " , userInfo : Dev . dave | Tag . sensitive )這些UserInfoHelpers我目前看到了一些當前的問題,這就是為什麼我現在將其設置為可選/實驗的原因。我很想听聽改進的評論/建議。
|只要沒有Set s,就可以合併字典。如果其中一個詞典包含一個Set ,則它將使用其中一個,而無需合併它們。如果雙方都有相同鍵的設置,則更喜歡左側。userInfo:參數需要字典,因此您不能傳遞單個開發對像或標記對象。您需要在|運算符使其自動轉換為兼容詞典。例如,如果您只想要一個標籤,則必須手動訪問.dictionary參數: userInfo: Tag("Blah").dictionary 。所有日誌方法均在封閉式上運行。使用與Swift的assert()函數相同的句法糖,此方法可確保我們不會浪費資源構建不會輸出的日誌消息,同時保留乾淨的呼叫站點。
例如,如果壓制調試日誌級別,則以下日誌語句不會浪費資源:
log . debug ( " The description of ( thisObject ) is really expensive to create " )同樣,假設您必須通過循環進行迭代,以便在記錄結果之前進行一些計算。在Objective-C中,您可以在#if #endif之間放置該代碼塊,並防止代碼運行。但是在Swift中,以前您需要仍需要處理該循環,浪費資源。使用XCGLogger ,它很簡單:
log . debug {
var total = 0.0
for receipt in receipts {
total += receipt . total
}
return " Total of all receipts: ( total ) "
}如果您希望在不生成日誌線的情況下選擇性執行代碼,請返回nil或使用其中一種方法: verboseExec , debugExec ,infoexec, infoExec , warningExec , errorExec和severeExec 。
您可以創建自己的DateFormatter對象並將其分配給記錄器。
let dateFormatter = DateFormatter ( )
dateFormatter . dateFormat = " MM/dd/yyyy hh:mma "
dateFormatter . locale = Locale . current
log . dateFormatter = dateFormatterXCGlogger支持將格式代碼添加到日誌消息中,以在各個地方啟用顏色。最初的選項是使用XcodeColors插件。但是,Xcode(從版本8開始)不再正式支持插件。您仍然可以在顏色上查看日誌,而目前不在Xcode中。您可以使用ANSI顏色支持來為您的歸檔對象添加顏色,並通過終端窗口查看日誌。這為您提供了一些額外的選擇,例如添加大膽,斜體或(請不要)眨眼!
啟用後,每個日誌級別都可以具有自己的顏色。這些顏色可以根據需要定制。如果使用多個記錄器,則可以將每個記錄儀設置為自己的顏色。
設置ANSI格式的一個示例:
if let fileDestination : FileDestination = log . destination ( withIdentifier : XCGLogger . Constants . fileDestinationIdentifier ) as? FileDestination {
let ansiColorLogFormatter : ANSIColorLogFormatter = ANSIColorLogFormatter ( )
ansiColorLogFormatter . colorize ( level : . verbose , with : . colorIndex ( number : 244 ) , options : [ . faint ] )
ansiColorLogFormatter . colorize ( level : . debug , with : . black )
ansiColorLogFormatter . colorize ( level : . info , with : . blue , options : [ . underline ] )
ansiColorLogFormatter . colorize ( level : . notice , with : . green , options : [ . italic ] )
ansiColorLogFormatter . colorize ( level : . warning , with : . red , options : [ . faint ] )
ansiColorLogFormatter . colorize ( level : . error , with : . red , options : [ . bold ] )
ansiColorLogFormatter . colorize ( level : . severe , with : . white , on : . red )
ansiColorLogFormatter . colorize ( level : . alert , with : . white , on : . red , options : [ . bold ] )
ansiColorLogFormatter . colorize ( level : . emergency , with : . white , on : . red , options : [ . bold , . blink ] )
fileDestination . formatters = [ ansiColorLogFormatter ]
}與過濾器一樣,您可以將相同的格式化對像用於多個登錄器和/或多個目的地。如果目標的formatters屬性nil ,則將使用Logger的formatters屬性。
有關創建自己的自定義格式化器的信息,請參見下面的XCGlogger。
通過使用Swift Build Frags,可以在調試與分期/生產中使用不同的日誌級別。轉到構建設置 - > Swift編譯器 - 自定義標誌 - >其他Swift標誌,然後將-DDEBUG添加到調試條目中。
#if DEBUG
log . setup ( level : . debug , showThreadName : true , showLevel : true , showFileNames : true , showLineNumbers : true )
#else
log . setup ( level : . severe , showThreadName : true , showLevel : true , showFileNames : true , showLineNumbers : true )
#endif您可以以類似的方式設置任何數量的選項。有關根據選項使用不同日誌目的地的示例,請參見更新的iosdemo應用程序,搜索USE_NSLOG 。
默認情況下,所提供的日誌目的地將處理被調用的線程上的日誌。這是為了確保在調試應用程序時立即顯示日誌消息。您可以在日誌調用後立即添加斷點,並在斷點命中時查看結果。
但是,如果您不積極調試應用程序,則處理當前線程上的日誌可能會引入性能點擊。現在,您可以在您選擇的調度隊列上指定目標進程的日誌(甚至使用默認提供的一個)。
fileDestination . logQueue = XCGLogger . logQueue甚至
fileDestination . logQueue = DispatchQueue . global ( qos : . background )當與上面的替代配置方法結合使用時,這非常有效。
#if DEBUG
log . setup ( level : . debug , showThreadName : true , showLevel : true , showFileNames : true , showLineNumbers : true )
#else
log . setup ( level : . severe , showThreadName : true , showLevel : true , showFileNames : true , showLineNumbers : true )
if let consoleLog = log . logDestination ( XCGLogger . Constants . baseConsoleDestinationIdentifier ) as? ConsoleDestination {
consoleLog . logQueue = XCGLogger . logQueue
}
#endif使用記錄器的高級配置(請參見上面的高級用法)時,您現在可以指定該記錄器附加到現有日誌文件,而不是自動覆蓋它。
添加可選的shouldAppend:初始化FileDestination對象時的參數。您還可以添加appendMarker:參數以將標記添加到日誌文件中,以指示應用程序的新實例開始附加。默認情況下,如果省略了參數,我們將添加-- ** ** ** --將其設置nil以跳過附加標記。
let fileDestination = FileDestination(writeToFile: "/path/to/file", identifier: "advancedLogger.fileDestination", shouldAppend: true, appendMarker: "-- Relauched App --")
登錄到文件時,您可以選擇將日誌文件自動旋轉到存檔的目標,並使Logger自動創建一個新的日誌文件,以代替舊文件。
使用AutoRotatingFileDestination類創建目的地,並設置以下屬性:
targetMaxFileSize :一旦文件大於此,自動旋轉
targetMaxTimeInterval :這秒後自動旋轉
targetMaxLogFiles :要保留的存檔日誌數量,較舊的日誌文件將自動刪除
這些都是記錄儀的準則,而不是硬限制。
您可以創建替代日誌目的地(內置的日誌目的地)。您的自定義日誌目標必須實現DestinationProtocol協議。實例化對象,配置它,然後將其添加到add(destination:)的XCGLogger對像中。您可以繼承兩個基本目標類( BaseDestination和BaseQueuedDestination ),以便為您處理大部分過程,要求您僅在自定義類中實現一種附加方法。查看ConsoleDestination和FileDestination的示例。
您還可以創建自定義過濾器或格式化器。看看提供的版本作為起點。請注意,過濾器和格式化器可以在處理時更改日誌消息。這意味著您可以創建一個過濾器,該過濾器剝離密碼,突出顯示特定單詞,加密消息等。
XCGlogger是Swift的最佳記錄儀,因為像您這樣的社區的貢獻。您可以通過多種方式可以幫助繼續使其變得偉大。
注意:提交拉動請求時,請使用許多巨大的提交經文。當需要組合新版本時需要合併幾個拉動請求時,它更容易合併。
如果您發現此庫有幫助,那麼您肯定會發現此其他工具有幫助:
看門狗:https://watchdogforxcode.com/
另外,請查看我的其他一些項目:
更改日誌現在在其自己的文件中:changelog.md