- GitHub: CocoaLumberjack
- star: 11.9k
CocoaLumberjack 是一個(gè)適用于 Mac 和 iOS 的快速、簡(jiǎn)單酣衷、功能強(qiáng)大且靈活的日志框架侈离。
如何開(kāi)始
通過(guò) CocoaPods 安裝
通過(guò) CocoaPods 安裝 Swift 版本
platform :ios, '8.0'
# You need to set target when you use CocoaPods 1.0.0 or later.
target 'SampleTarget' do
use_frameworks!
pod 'CocoaLumberjack/Swift'
end
注意: Swift
子空間中包含了所有的 Objectice-C 代碼和 Swift 代碼,所以這是足夠的。
For more details about how to use Swift with Lumberjack, see this conversation.
Swift 用法
如果你通過(guò) CocoaPods 或者手動(dòng)方式導(dǎo)入框架:
import CocoaLumberjack
DDLog.add(DDTTYLogger.sharedInstance) // TTY = Xcode console
DDLog.add(DDASLLogger.sharedInstance) // ASL = Apple System Logs
let fileLogger: DDFileLogger = DDFileLogger() // File Logger
fileLogger.rollingFrequency = TimeInterval(60*60*24) // 24 hours
fileLogger.logFileManager.maximumNumberOfLogFiles = 7
DDLog.add(fileLogger)
...
DDLogVerbose("Verbose");
DDLogDebug("Debug");
DDLogInfo("Info");
DDLogWarn("??");
DDLogError("Error");
通過(guò) CocoaPods 安裝 Objectice-C 版本
對(duì)于 Objective-C勘高,請(qǐng)使用以下命令:
platform :ios, '8.0'
target 'SampleTarget' do
pod 'CocoaLumberjack'
end
Objectice-C 用法
如果你把 Lumberjack 作為框架導(dǎo)入帝嗡,你可以使用 @import CocoaLumberjack
或者 #import <CocoaLumberjack/CocoaLumberjack.h>
晶通。
[DDLog addLogger:[DDTTYLogger sharedInstance]]; // TTY = Xcode 控制臺(tái)
[DDLog addLogger:[DDASLLogger sharedInstance]]; // ASL = Apple System Logs 蘋(píng)果系統(tǒng)日志
// 創(chuàng)建本地日志文件
DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
fileLogger.rollingFrequency = 60 * 60 * 24; // 每24小時(shí)創(chuàng)建一個(gè)新文件
fileLogger.logFileManager.maximumNumberOfLogFiles = 7; // 最多允許創(chuàng)建7個(gè)文件
[DDLog addLogger:fileLogger];
...
DDLogVerbose(@"Verbose");
DDLogDebug(@"Debug");
DDLogInfo(@"Info");
DDLogWarn(@"Warn");
DDLogError(@"Error");
使用 Carthage (iOS 8+) 安裝
Carthage is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and is less invasive than CocoaPods.
To install with Carthage, follow the instruction on Carthage
Cartfile
github "CocoaLumberjack/CocoaLumberjack"
- or install manually
- read the Getting started guide, check out the FAQ section or the other docs
- if you find issues or want to suggest improvements, create an issue or a pull request
- for all kinds of questions involving CocoaLumberjack, use the Google group or StackOverflow (use #lumberjack).
CocoaLumberjack 3
遷移到 3.x
- 待定
特性
Lumberjack 是 快速 & 簡(jiǎn)單, 而且強(qiáng)大 & 靈活的.
它在概念上與其他流行的日志記錄框架類似,如log4j哟玷,它是專為 Objective-C 設(shè)計(jì)的狮辽,并且利用了諸如多線程,GCD(如果可用)巢寡,無(wú)鎖原子操作(lockless atomic operations)和動(dòng)態(tài)性質(zhì)的 Objective-C runtime喉脖。
Lumberjack 更快速
在大多數(shù)情況下,它比 NSLog
快一個(gè)數(shù)量級(jí)抑月。
Lumberjack 是簡(jiǎn)單的
當(dāng)應(yīng)用程序啟動(dòng)時(shí)树叽,它幾乎只需要一行代碼來(lái)配置 lumberjack。 然后只需用 DDLog
語(yǔ)句替換您的 NSLog
語(yǔ)句即可爪幻。 (并且 DDLog
宏與 NSLog
具有完全相同的格式和語(yǔ)法菱皆,因此它非常簡(jiǎn)單。)
Lumberjack 是強(qiáng)大的
一條日志語(yǔ)句可以被發(fā)送到多個(gè)記錄器上挨稿,這意味著你可以同時(shí)登錄到文件和控制臺(tái)仇轻。 想要更多? 創(chuàng)建自己的記錄器(很簡(jiǎn)單)奶甘,并通過(guò)網(wǎng)絡(luò)發(fā)送您的日志篷店。 或者到數(shù)據(jù)庫(kù)或分布式文件系統(tǒng)。 限制它的只有天空(The sky is the limit)臭家。
Lumberjack 是靈活的:
配置你需要記錄的日志疲陕。 更改每個(gè)文件的日志級(jí)別(便于完美調(diào)試)。更改每個(gè)記錄器的日志級(jí)別(詳細(xì)的控制臺(tái)钉赁,但簡(jiǎn)明的日志文件)蹄殃。 更改每個(gè) Xcode 配置的日志級(jí)別(詳細(xì)調(diào)試,但簡(jiǎn)明扼要)你踩。 將日志語(yǔ)句從發(fā)行版本中編譯出來(lái)诅岩。 自定義應(yīng)用程序的日志級(jí)別數(shù)量。 添加適合你自己的日志带膜。 在運(yùn)行時(shí)動(dòng)態(tài)更改日志級(jí)別吩谦。 選擇如何以及何時(shí)希望日志文件滾動(dòng)。 將日志文件上傳到中央服務(wù)器膝藕。 壓縮歸檔日志文件以節(jié)省磁盤(pán)空間...
這個(gè)框架就是為你準(zhǔn)備的如果:
- 你正在尋找一種方法來(lái)追蹤不可再現(xiàn)的錯(cuò)誤式廷,這些錯(cuò)誤在該領(lǐng)域不斷涌現(xiàn)。
- 你對(duì) iPhone 上的超短控制臺(tái)日志感到沮喪芭挽。
- 你正在尋求在支持性和穩(wěn)定性方面將應(yīng)用提升到一個(gè)新的水平滑废。
- 你正在為你的應(yīng)用程序(Mac或iPhone)尋找企業(yè)級(jí)日志記錄解決方案蝗肪。
文檔
- Get started using Lumberjack
- Different log levels for Debug and Release builds
- Different log levels for each logger
- Use colors in the Xcode debugging console
- Write your own custom formatters
- FAQ
- Analysis of performance with benchmarks
- Common issues you may encounter and their solutions
- AppCode support
- Full Lumberjack documentation
配置需求
當(dāng)前版本的 Lumberjack 需要:
- Xcode 11 or later
- Swift 5.0 or later
- iOS 8 or later
- OS X 10.10 or later
- WatchOS 3 or later
- TVOS 9 or later
向后兼容性
- for Xcode 7.3 and Swift 2.3, use the 2.4.0 version
- for Xcode 7.3 and Swift 2.2, use the 2.3.0 version
- for Xcode 7.2 and 7.1, use the 2.2.0 version
- for Xcode 7.0 or earlier, use the 2.1.0 version
- for Xcode 6 or earlier, use the 2.0.x version
- for OS X < 10.7 support, use the 1.6.0 version
溝通
- If you need help, use Stack Overflow. (Tag 'lumberjack')
- If you'd like to ask a general question, use Stack Overflow.
- If you found a bug, open an issue.
- If you have a feature request, open an issue.
- If you want to contribute, submit a pull request.
作者
- Robbie Hanson
- Love the project? Wanna buy me a coffee? (or a beer :D) [圖片上傳失敗...(image-d928bf-1510647423281)]
Collaborators
License
CocoaLumberjack is available under the BSD license. See the LICENSE file.
項(xiàng)目結(jié)構(gòu)
?? 光看以上官方的 README 文檔其實(shí)是完全不夠的,我發(fā)現(xiàn)實(shí)際項(xiàng)目中使用時(shí)還是有很多注意點(diǎn)策严,最好詳細(xì)看看 Documentation 里面的文章穗慕。
使用此框架前,打印日志是這么做的
記錄日志的一般做法是在 Release 模式下禁用 NSLog
妻导,比如在 .pch
文件中逛绵,通過(guò)對(duì)環(huán)境的判斷,對(duì) NSLog
做不同的處理倔韭。因此术浪,在不使用 CocoaLumberjack 之前,我的 .pch
預(yù)編譯頭文件中是這樣寫(xiě)的:
/****************** 打印日志 ******************/
#ifdef DEBUG
#define HQString [NSString stringWithFormat:@"%s", __FILE__].lastPathComponent
#define HQLog(...) printf("%s: %s 第%d行:\n %s\n\n", [[NSString hql_stringDate] UTF8String], [HQString UTF8String] , __LINE__, [[NSString stringWithFormat:__VA_ARGS__] UTF8String]);
#else
#define HQLog(...);
#endif /* DEBUG */
還需要為 NSString
類創(chuàng)建一個(gè)范疇類的方法來(lái)格式化輸出時(shí)間:
+ (NSString *)hql_stringDate {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"YYYY-MM-dd hh:mm:ss"];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
return dateString;
}
項(xiàng)目中使用CocoaLumberjack
Getting started with the CocoaLumberjack framework.
項(xiàng)目中集成并使用 CocoaLumberjack 分為三步:
- 添加 CocoaLumberjack 文件到項(xiàng)目中寿酌;
- 鏈接配置 CocoaLumberjack胰苏;
- 將你的
NSLog
語(yǔ)句轉(zhuǎn)換為使用 CocoaLumberjack 宏;
添加 CocoaLumberjack 框架到項(xiàng)目中
通過(guò) Cocoapods 添加:
platform :ios, '8.0'
pod 'CocoaLumberjack'
鏈接配置 CocoaLumberjack
- 引入頭文件
#define LOG_LEVEL_DEF ddLogLevel
#import <CocoaLumberjack/CocoaLumberjack.h>
- 設(shè)置全局狀態(tài) Log 級(jí)別
static const DDLogLevel ddLogLevel = DDLogLevelDebug;
- 以上兩個(gè)步驟在
.pch
中設(shè)置如下:
/** 打印日志 */
#define LOG_LEVEL_DEF ddLogLevel
#import <CocoaLumberjack/CocoaLumberjack.h>
#ifdef DEBUG
static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
#else
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#endif /* DEBUG */
-
AppDelegate.m
文件
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (@available(iOS 10.0, *)) {
// Uses os_log
[DDLog addLogger:[DDOSLogger sharedInstance]];
} else {
// TTY = Xcode 控制臺(tái)
// DDTTYLogger,你的日志語(yǔ)句將被發(fā)送到 Xcode 控制臺(tái)
[DDLog addLogger:[DDTTYLogger sharedInstance]];
}
// DDASLLogger醇疼,你的日志語(yǔ)句將被發(fā)送到蘋(píng)果文件系統(tǒng)硕并、你的日志狀態(tài)會(huì)被發(fā)送到 Console.app
[DDLog addLogger:[DDASLLogger sharedInstance]];
// DDFileLogger,你的日志語(yǔ)句將寫(xiě)入到一個(gè)文件中秧荆,默認(rèn)路徑在沙盒的Library/Caches/Logs/目錄下倔毙,文件名為bundleid+空格+日期.log。
DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
fileLogger.rollingFrequency = 60 * 60 * 24; // 刷新頻率為24小時(shí)
fileLogger.logFileManager.maximumNumberOfLogFiles = 7; // 保存一周的日志乙濒,即7天
[DDLog addLogger:fileLogger];
// 日常使用時(shí)陕赃,打印日志方法如下
DDLogVerbose(@"Verbose"); // 詳細(xì)日志
DDLogDebug(@"Debug"); // 調(diào)試日志
DDLogInfo(@"Info"); // 信息日志
DDLogWarn(@"Warn"); // 警告日志
DDLogError(@"Error"); // 錯(cuò)誤日志
return YES;
}
運(yùn)行程序,查看 Xocde 控制臺(tái)日志:
?? 你會(huì)發(fā)現(xiàn)控制臺(tái)日志打印了兩遍颁股,那是因?yàn)樵谂渲弥形覀兺瑫r(shí)添加了 Xcode 控制臺(tái)日志和 DDASLLogger 日志么库,開(kāi)發(fā)中注釋掉配置的 DDASLLogger 日志即可。
在項(xiàng)目中使用 CocoaLumberjack 框架前后的變化:
// 原生的 NSLog 方法:
NSLog(@"Broken sprocket detected!");
NSLog(@"User selected file:%@ withSize:%u", filePath, fileSize);
// 集成了 CocoaLumberjack 框架之后的用法:
DDLogError(@"Broken sprocket detected!");
DDLogVerbose(@"User selected file:%@ withSize:%u", filePath, fileSize);
正如你所看到的那樣甘有,DDLog
宏與 NSLog
具有完全相同的語(yǔ)法诉儒。
CocoaLumberjack 的日志類型
- DDLog(整個(gè)框架的基礎(chǔ))
- DDASLLogger(發(fā)送日志到蘋(píng)果的日志系統(tǒng),以便它們顯示在 Console.app 上)
- DDTTYLoyger(發(fā)送日志到 Xcode 控制臺(tái))
- DDFIleLoger(把日志寫(xiě)入本地文件)
CocoaLumberjack 的日志級(jí)別
你需要考慮使用哪種日志級(jí)別亏掀,CocoaLumberjack 一共提供了 5 種 DDLogFlag
:
typedef NS_OPTIONS(NSUInteger, DDLogFlag){
DDLogFlagError = (1 << 0),
DDLogFlagWarning = (1 << 1),
DDLogFlagInfo = (1 << 2),
DDLogFlagDebug = (1 << 3),
DDLogFlagVerbose = (1 << 4)
};
DDLogLevel
用來(lái)過(guò)濾每條日志
typedef NS_ENUM(NSUInteger, DDLogLevel){
DDLogLevelOff = 0,
DDLogLevelError = (DDLogFlagError),
DDLogLevelWarning = (DDLogLevelError | DDLogFlagWarning),
DDLogLevelInfo = (DDLogLevelWarning | DDLogFlagInfo),
DDLogLevelDebug = (DDLogLevelInfo | DDLogFlagDebug),
DDLogLevelVerbose = (DDLogLevelDebug | DDLogFlagVerbose),
DDLogLevelAll = NSUIntegerMax
};
例如允睹,如果你將日志級(jí)別設(shè)置為 DDLogLevelInfo
,那么你會(huì)看到 DDLogLevelError
幌氮、DDLogLevelWarning
和 DDLogLevelInfo
級(jí)別的日志。
你也可以自定義Log級(jí)別或者每個(gè)級(jí)別的名字或者在單純的級(jí)別上增加一些高級(jí)用法
我們也可以為Debug和Release模式設(shè)置不同的日志級(jí)別:
Xcode 4+ :
#ifdef DEBUG
static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
#else
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#endif
我們還可以為每種 logger 記錄器設(shè)置不同的日志級(jí)別:
如果你需要為每個(gè) logger 記錄器使用不同的日志級(jí)別(即胁澳,如果你有自定義記錄器该互,如Crashlytics記錄器,它不應(yīng)該記錄 Info 或 Debug)韭畸,你就可以使用 [DDLog addLogger:withLevel:]
方法輕松實(shí)現(xiàn)宇智。
[DDLog addLogger:[DDASLLogger sharedInstance] withLevel:DDLogLevelInfo];
[DDLog addLogger:[DDTTYLogger sharedInstance] withLevel:DDLogLevelDebug];
你仍然可以使用舊的類方法+ addLogger:
蔓搞,該方法使用 DDLogLevelVerbose 作為默認(rèn)值,它不會(huì)排除任何日志随橘。
你可以通過(guò) [DDLog allLoggersWithLevel]
方法檢索與 DDLog 關(guān)聯(lián)的每個(gè)記錄器和級(jí)別的列表喂分。
自定義日志格式
// .h
#import <Foundation/Foundation.h>
#import <DDLog.h>
@interface HQLCustomFormatter : NSObject <DDLogFormatter> {
int atomicLoggerCount;
NSDateFormatter *threadUnsafeDateFormatter;
}
@end
// .m
#import "HQLCustomFormatter.h"
#import <libkern/OSAtomic.h>
static NSString *const KdateFormatString = @"yyyy/MM/dd HH:mm:ss";
@implementation HQLCustomFormatter
- (NSString *)stringFromDate:(NSDate *)date {
int32_t loggerCount = OSAtomicAdd32(0, &atomicLoggerCount);
if (loggerCount <= 1) {
// Single-threaded mode.
if (threadUnsafeDateFormatter == nil) {
threadUnsafeDateFormatter = [[NSDateFormatter alloc] init];
[threadUnsafeDateFormatter setDateFormat:KdateFormatString];
}
return [threadUnsafeDateFormatter stringFromDate:date];
} else {
// Multi-threaded mode.
// NSDateFormatter is NOT thread-safe.
NSString *key = @"MyCustomFormatter_NSDateFormatter";
NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
NSDateFormatter *dateFormatter = [threadDictionary objectForKey:key];
if (dateFormatter == nil) {
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:KdateFormatString];
[threadDictionary setObject:dateFormatter forKey:key];
}
return [dateFormatter stringFromDate:date];
}
}
#pragma mark - DDLogFormatter
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
NSString *logLevel; // 日志等級(jí)
switch (logMessage->_flag) {
case DDLogFlagError : logLevel = @"Error"; break;
case DDLogFlagWarning : logLevel = @"Warning"; break;
case DDLogFlagInfo : logLevel = @"Info"; break;
case DDLogFlagDebug : logLevel = @"Debug"; break;
default : logLevel = @"Verbose"; break;
}
NSString *dateAndTime = [self stringFromDate:(logMessage.timestamp)]; // 日期和時(shí)間
NSString *logFileName = logMessage -> _fileName; // 文件名
NSString *logFunction = logMessage -> _function; // 方法名
NSUInteger logLine = logMessage -> _line; // 行號(hào)
NSString *logMsg = logMessage->_message; // 日志消息
// 日志格式:日期和時(shí)間 文件名 方法名 : 行數(shù) <日志等級(jí)> 日志消息
return [NSString stringWithFormat:@"%@ %@ %@ : %lu <%@> %@", dateAndTime, logFileName, logFunction, logLine, logLevel, logMsg];
}
- (void)didAddToLogger:(id <DDLogger>)logger {
OSAtomicIncrement32(&atomicLoggerCount);
}
- (void)willRemoveFromLogger:(id <DDLogger>)logger {
OSAtomicDecrement32(&atomicLoggerCount);
}
@end
最后,自定義好日志之后記得添加到全局的配置中:
[DDTTYLogger sharedInstance].logFormatter = [[HQLCustomFormatter alloc] init]; // 自定義日志
[DDLog addLogger:[DDTTYLogger sharedInstance]]; // TTY = Xcode console
[DDLog addLogger:[DDASLLogger sharedInstance]]; // ASL = Apple System Logs
DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; // File Logger
fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling
fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
[DDLog addLogger:fileLogger];
更多文檔詳情請(qǐng)查看 CocoaLumberjack Documentation
遇到的問(wèn)題
解決方法
參考 Getting started with the CocoaLumberjack framework.
#define LOG_LEVEL_DEF ddLogLevel // 要先設(shè)置宏定義
#import <CocoaLumberjack/CocoaLumberjack.h>
#ifdef DEBUG
static const DDLogLevel ddLogLevel = DDLogLevelVerbose; // ddLogLevel 注意大小寫(xiě)要與上面宏定義中保持一致
#else
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#endif /* DEBUG */