UALogger 是一个简单轻量级的日志工具,适用于 iOS 和 macOS 应用。它允许您自定义日志格式,自定义在运行时何时将日志输出到控制台,并允许收集应用程序的完整最近控制台日志。它包括 UALogger
类和类方法,以及一些便捷的宏。
NSLog
很好,但仍有改进的空间。您可能项目中有些代码像是以下的,最终以一些通用且无用的方式使用如下:
NSLog(@"Error: %@", [error localizedDescription]);
=> Error: There was a problem loading resource.
UALogger 跳出来帮助。只需简单地添加文件和行号(基本格式)到输出来,您可以将通用日志消息放入上下文中,使它们成为更强大反馈方法。
UALog(@"Error: %@", [error localizedDescription]);
=> <UAViewController.m:27> Error: There was a problem loading resource.
NSLog
调用开销很大。每次写入都要在操作系统的文件中追加一行,这意味着文件必须被定位、打开、追加、保存,并且所有操作都是同步的。这里的 NSLog
调用不会使您的应用崩溃,但如果你经常使用日志(你应该这样),它可能会对性能造成影响。
那么你如何避免在生产中日志记录?你是否在部署前对 NSLog
条目进行 grep 并使用注释来删除它们?不。你只需安装 UALogger 就不用再担心这个问题。除非您显式重写它,否则 UALogger 不会在生产构建中向控制台写入日志。另外,生产日志可以在 运行时 启用或禁用。
NSLog
写入的控制台日志可以被任何应用读取,或者任何知道如何在设备上挖掘的人读取。这可能不是一个问题,但如果您记录用户信息,如电子邮件或密码怎么办?如果记录了您私有 API 的 URL 或后端服务的详细信息怎么办?当您使用 UALogger 时,您将不会在生产中将这些日志打印到系统控制台,保护您和您的用户。
UALogger让您能将应用生成的所有日志记录到系统日志中。在我们的主应用Ambiance中,我们使用它来帮助调试难以解决的用户问题。如果客户联系我们反馈了一个我们难以解决的问题,我们会要求他们在应用程序设置中打开Ambiance的日志记录功能,尝试重现问题,然后通过应用程序中的按钮将日志发送给我们。
UALogger允许您在日志记录时使用严重性级别,以便只通过重要的日志。这在日志记录生产中的严重错误和关键消息时很有用。
使用Cocoapods可以使安装变得简单。如果您想用老方法安装,只需将UALogger.h
和UALogger.m
添加到您的项目中即可。
pod 'UALogger', '~> 0.2.3'
然后,只需将此行放入您的prefix.pch
文件中,就可以从所有源文件中访问记录器。
#import <UALogger.h>
UALogBasic
的记录方式和NSLog
一样,但还记录了文件名和行号。
UALogBasic(@"Foobar");
=> <UAViewController.m:27> Foobar
UALogFull
记录调用对象(self)、文件名、行号和方法名。
UALogFull(@"Foobar");
=> <0xb26b730 UAViewController.m:28 (viewDidLoad)> Foobar
UALogPlain
以与NSLog相同的方式记录到控制台,没有其他信息。
UALogPlain(@"Foobar");
=> Foobar
UALog
是UALogBasic
的简称。
使用UALogger
的一个简单方法是进行项目范围内的查找和替换,将NSLog
更改为UALog
。
UALog(@"This used to be an NSLog()");
=> <UAViewController.m:27> This used to be an NSLog()
UALog
默认设置为调用UALogBasic
,但您可以通过在prefix.pch
文件中紧接#import <UALogger.h>
后添加以下内容来更改这一点
#import <UALogger.h>
#undef UALog;
#define UALog( s, ... ) UALogPlain( s, ##__VA_ARGS__ );
或
#import <UALogger.h>
#undef UALog;
#define UALog( s, ... ) UALogFull( s, ##__VA_ARGS__ );
UALogger
将与NSLog
无缝协同工作,但是,如果您设置了一个名为UALOGGER_SWIZZLE_NSLOG
的预处理器宏,则可以在不更改任何代码的情况下使用UALogger
。
NSLog(@"This NSLog call is actually routing through UALogger.");
=> <0xb26b730 UAViewController.m:28 (viewDidLoad)> This NSLog call is actually routing through UALogger.
只有从已导入UALogger.h
的文件中调用NSLog
时,才会通过UALogger
路由。如果您在prefix.pch
中导入了UALogger
,这意味着所有文件都会这样做。
尽管它会使得生活更轻松,但您不必使用任何UALogger
宏来使用UALogger
。您可以使用简单的调用记录任何内容
[UALogger log:@"I am logging now: %@", [NSDate date]];
=> I am logging now: 2013-09-02 12:42:31 +0000
请注意,以这种方式记录日志不会预置任何其他信息。这是因为无法从UALogger
类内部确定调用文件名和日志行、方法名等……。尽管如此,宏知道这些信息,建议您使用它们以最大限度地发挥UALogger
的优势。
如果您只是想更改日志的显示方式,可以通过在运行时更改格式字符串来定制UALogPlain
、UALogBasic
和UALogFull
调用的格式
[UALogger setFormat:@"Foobar! %@" forVerbosity:UALoggerVerbosityPlain];
UALogPlain(@"Barfoo%@?", @"d");
=> Foobar! Barfood?
然后,所有后续的日志调用都将使用该格式。有关默认格式及其所期望变量顺序的更多信息,请参阅setupDefaultFormats
方法。如果要重置格式,请调用
[UALogger resetDefaultLogFormats];
默认情况下,UALogger会在调试环境中记录日志,而在生产环境中不会。它通过判断预处理宏DEBUG
的存在来决定这一点,该宏默认添加到每个Xcode项目中。它用来判断是否向控制台应该记录日志的规则是
shouldLogInDebug
为真或者shouldLogInProduction
为真或者您可以在运行时查询这些值并设置其中一些。
[+ isProduction]
返回真,如果在编译过程中没有找到DEBUG
宏。
BOOL isProduction = [UALogger isProduction];
[+ shouldLogInProduction]
默认设置为NO
,但可以被设置为其他值
BOOL shouldLogInProduction = [UALogger shouldLogInProduction];
if (shouldLogInProduction)
[UALogger setShouldLogInProduction:NO];
[+ shouldLogInDebug]
默认设置为YES
,但可以被设置为其他值
BOOL shouldLogInDebug = [UALogger shouldLogInDebug];
if (!shouldLogInDebug)
[UALogger setShouldLogInDebug:YES];
[+ userDefaultsKey]
是用于查找手动日志替换的键。最常见的使用是将其与App设置中的开关连接,以打开日志记录。默认情况下,此键设置为UALogger_LoggingEnabled
,但可以被设置为返回BOOL
的任何内容。
NSString *userDefaultsKey = [UALogger userDefaultsKey];
if ([userDefaultsKey isEqualToString:UALogger_LoggingEnabled])
[UALogger setUserDefaultsKey:@"CustomizedUserDefaultsKey"];
可能需要更改此值的示例是,如果您想记录特定功能启用时的情况——比如您有一个高端的、但还在测试阶段的功能X;
BOOL featureXIsEnabled = [[NSUserDefaults standardDefaults] boolForKey:@"featureXIsEnabled"];
[UALogger setUserDefaultsKey:@"featureXIsEnabled"];
将记录器设置为使用相同的键意味着当该功能开启时,将会记录日志。
[+ loggingEnabled]
是UALogger用来判断是否应该记录一行的方法。它使用上述算法和方法返回一个简单的BOOL
。
BOOL loggingEnabled = [UALogger loggingEnabled];
UALogger还可以配置为与日志严重级别一起使用。每个三个日志宏(UALogPlain
、UALogBasic
和UALogFull
)都有一个变体,允许您传递一个UALoggerSeverity
UASLogPlain
UASLogBasic
UASLogFull
UASLog
// 默认为 UASLogBasicS
代表严重性,是这些函数的第一个参数。UALogger识别5种严重性
UALoggerSeverityDebug
// 最低日志级别UALoggerSeverityInfo
UALoggerSeverityWarn
UALoggerSeverityError
UALoggerSeverityFatal
// 最高日志级别要使用严重级别,您必须设置一个minimumSeverity
给UALogger使用
[UALogger setMinimumSeverity:UALoggerSeverityWarn];
默认情况下,严重性是UALoggerSeverityUnset
,因此不用于确定何时记录。但是,一旦您设置了其他minimumSeverity
,则将只使用minimumSeverity
来确定何时记录。
示例
[UALogger setMinimumSeverity:UALoggerSeverityWarn];
UASLog(UALoggerSeverityDebug, @" - Logged with severity => UALoggerSeverityDebug");
UASLog(UALoggerSeverityInfo, @" - Logged with severity => UALoggerSeverityInfo");
UASLog(UALoggerSeverityWarn, @" - Logged with severity => UALoggerSeverityWarn");
UASLog(UALoggerSeverityError, @" - Logged with severity => UALoggerSeverityError");
UASLog(UALoggerSeverityFatal, @" - Logged with severity => UALoggerSeverityFatal");
UASLog(UALoggerSeverityFatal, @" - Only 3 of the above lines are logged because they meet or exceed the minimumSeverity (UALoggerSeverityWarn)");
设置minimumSeverity
之后,除非取消设置,否则调用非S函数将不会记录。
[UALogger setMinimumSeverity:UALoggerSeverityDebug];
UALog(@"This will not log.");
UASLog(UALoggerSeverityDebug, @"This will log.");
[UALogger setMinimumSeverity:UALoggerSeverityUnset];
UALog(@"This will log.");
UASLog(UALoggerSeverityDebug, @"This will log, and the severity ignored");
请调用此方法来获取控制台的最近日志条目。
[UALogger applicationLog];
这对于自动将支持电子邮件(由App内发起)附加到您的应用非常有用。
NSString *log = [UALogger applicationLog];
NSData *data = [log dataUsingEncoding:NSUTF8StringEncoding];
[mailComposeViewController addAttachmentData:data mimeType:@"text/plain" fileName:@"ApplicationLog.txt"];
applicationLog
方法为同步方法,可能需要一段时间,因此还有一个基于异步块的方法,具有onComplete回调。
[UALogger getApplicationLog:^(NSArray *logs){
for (NSString *log in logs) {
// Do something awesome"
}
}];
请注意,它仅查找写入控制台日志的条目,因此如果您没有启用记录,则将不会返回任何行。它能够检查整个控制台日志,但不能查看文件被轮换后的以前的日志。对于常规使用,您通常可以获取一天或更长时间的日志条目。
请查看示例项目,了解如何使用UALogger、如何设置开关以在野外打开/关闭日志记录,以及如何将应用日志附加到电子邮件。
对于UALogger的未来版本,我们有一些想法。如果您想加快进程,请随时分叉/实现。
error
、critical
、warning
等的可选日志优先级系统……然后我们可以设置一个阈值来记录,所有符合或超过该阈值严重性的内容都会被记录。这允许日志打印由数据驱动。例如 UALog(UALoggerSeverityCritical, @"Error: %@", [error localizedDescription]
;如果您看到改进 UALogger
的方法或认为它有问题,请告诉我们。我们很高兴接受那些代码整洁并且具有大多数人有用功能的拉取请求。
截图很酷。日志控制台截图不酷。伐木工的图片很酷。
Urban Apps. 我们制作一些很酷的东西。查看我们。
如果您想为我们开源UALogger表示感谢,您可以购买我们的任一应用程序,或者甚至捐献一点小东西。